aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/KeyframeMotion.cs513
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs66
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs170
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs6
6 files changed, 524 insertions, 270 deletions
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
index 5cfba39..b102e48 100644
--- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
+++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
@@ -22,6 +22,115 @@ using log4net;
22 22
23namespace OpenSim.Region.Framework.Scenes 23namespace OpenSim.Region.Framework.Scenes
24{ 24{
25 public class KeyframeTimer
26 {
27 private static Dictionary<Scene, KeyframeTimer>m_timers =
28 new Dictionary<Scene, KeyframeTimer>();
29
30 private Timer m_timer;
31 private Dictionary<KeyframeMotion, object> m_motions = new Dictionary<KeyframeMotion, object>();
32 private object m_lockObject = new object();
33 private object m_timerLock = new object();
34 private const double m_tickDuration = 50.0;
35 private Scene m_scene;
36
37 public double TickDuration
38 {
39 get { return m_tickDuration; }
40 }
41
42 public KeyframeTimer(Scene scene)
43 {
44 m_timer = new Timer();
45 m_timer.Interval = TickDuration;
46 m_timer.AutoReset = true;
47 m_timer.Elapsed += OnTimer;
48
49 m_scene = scene;
50
51 m_timer.Start();
52 }
53
54 private void OnTimer(object sender, ElapsedEventArgs ea)
55 {
56 if (!Monitor.TryEnter(m_timerLock))
57 return;
58
59 try
60 {
61 List<KeyframeMotion> motions;
62
63 lock (m_lockObject)
64 {
65 motions = new List<KeyframeMotion>(m_motions.Keys);
66 }
67
68 foreach (KeyframeMotion m in motions)
69 {
70 try
71 {
72 m.OnTimer(TickDuration);
73 }
74 catch (Exception inner)
75 {
76 // Don't stop processing
77 }
78 }
79 }
80 catch (Exception e)
81 {
82 // Keep running no matter what
83 }
84 finally
85 {
86 Monitor.Exit(m_timerLock);
87 }
88 }
89
90 public static void Add(KeyframeMotion motion)
91 {
92 KeyframeTimer timer;
93
94 if (motion.Scene == null)
95 return;
96
97 lock (m_timers)
98 {
99 if (!m_timers.TryGetValue(motion.Scene, out timer))
100 {
101 timer = new KeyframeTimer(motion.Scene);
102 m_timers[motion.Scene] = timer;
103 }
104 }
105
106 lock (timer.m_lockObject)
107 {
108 timer.m_motions[motion] = null;
109 }
110 }
111
112 public static void Remove(KeyframeMotion motion)
113 {
114 KeyframeTimer timer;
115
116 if (motion.Scene == null)
117 return;
118
119 lock (m_timers)
120 {
121 if (!m_timers.TryGetValue(motion.Scene, out timer))
122 {
123 return;
124 }
125 }
126
127 lock (timer.m_lockObject)
128 {
129 timer.m_motions.Remove(motion);
130 }
131 }
132 }
133
25 [Serializable] 134 [Serializable]
26 public class KeyframeMotion 135 public class KeyframeMotion
27 { 136 {
@@ -63,18 +172,6 @@ namespace OpenSim.Region.Framework.Scenes
63 172
64 private Keyframe[] m_keyframes; 173 private Keyframe[] m_keyframes;
65 174
66 [NonSerialized()]
67 protected Timer m_timer = null;
68
69 // timer lock
70 [NonSerialized()]
71 private object m_onTimerLock;
72
73 // timer overrun detect
74 // prevents overlap or timer events threads frozen on the lock
75 [NonSerialized()]
76 private bool m_inOnTimer;
77
78 // skip timer events. 175 // skip timer events.
79 //timer.stop doesn't assure there aren't event threads still being fired 176 //timer.stop doesn't assure there aren't event threads still being fired
80 [NonSerialized()] 177 [NonSerialized()]
@@ -97,12 +194,21 @@ namespace OpenSim.Region.Framework.Scenes
97 private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation; 194 private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation;
98 195
99 private bool m_running = false; 196 private bool m_running = false;
197
100 [NonSerialized()] 198 [NonSerialized()]
101 private bool m_selected = false; 199 private bool m_selected = false;
102 200
103 private int m_iterations = 0; 201 private int m_iterations = 0;
104 202
105 private const double timerInterval = 50.0; 203 private int m_skipLoops = 0;
204
205 [NonSerialized()]
206 private Scene m_scene;
207
208 public Scene Scene
209 {
210 get { return m_scene; }
211 }
106 212
107 public DataFormat Data 213 public DataFormat Data
108 { 214 {
@@ -139,31 +245,16 @@ namespace OpenSim.Region.Framework.Scenes
139 245
140 private void StartTimer() 246 private void StartTimer()
141 { 247 {
142 if (m_timer == null) 248 KeyframeTimer.Add(this);
143 return;
144 m_timerStopped = false; 249 m_timerStopped = false;
145 m_timer.Start();
146 } 250 }
147 251
148 private void StopTimer() 252 private void StopTimer()
149 { 253 {
150 if (m_timer == null || m_timerStopped)
151 return;
152 m_timerStopped = true;
153 m_timer.Stop();
154 }
155
156 private void RemoveTimer()
157 {
158 if (m_timer == null)
159 return;
160 m_timerStopped = true; 254 m_timerStopped = true;
161 m_timer.Stop(); 255 KeyframeTimer.Remove(this);
162 m_timer.Elapsed -= OnTimer;
163 m_timer = null;
164 } 256 }
165 257
166
167 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) 258 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data)
168 { 259 {
169 KeyframeMotion newMotion = null; 260 KeyframeMotion newMotion = null;
@@ -177,12 +268,15 @@ namespace OpenSim.Region.Framework.Scenes
177 268
178 newMotion.m_group = grp; 269 newMotion.m_group = grp;
179 270
180 if (grp != null && grp.IsSelected) 271 if (grp != null)
181 newMotion.m_selected = true; 272 {
273 newMotion.m_scene = grp.Scene;
274 if (grp.IsSelected)
275 newMotion.m_selected = true;
276 }
182 277
183 newMotion.m_onTimerLock = new object();
184 newMotion.m_timerStopped = false; 278 newMotion.m_timerStopped = false;
185 newMotion.m_inOnTimer = false; 279 newMotion.m_running = true;
186 newMotion.m_isCrossing = false; 280 newMotion.m_isCrossing = false;
187 newMotion.m_waitingCrossing = false; 281 newMotion.m_waitingCrossing = false;
188 } 282 }
@@ -196,37 +290,36 @@ namespace OpenSim.Region.Framework.Scenes
196 290
197 public void UpdateSceneObject(SceneObjectGroup grp) 291 public void UpdateSceneObject(SceneObjectGroup grp)
198 { 292 {
199// lock (m_onTimerLock) 293 m_isCrossing = false;
200 { 294 m_waitingCrossing = false;
201 m_isCrossing = false; 295 StopTimer();
202 m_waitingCrossing = false;
203 StopTimer();
204 296
205 if (grp == null) 297 if (grp == null)
206 return; 298 return;
207 299
208 m_group = grp; 300 m_group = grp;
209 Vector3 grppos = grp.AbsolutePosition; 301 m_scene = grp.Scene;
210 Vector3 offset = grppos - m_serializedPosition;
211 // avoid doing it more than once
212 // current this will happen draging a prim to other region
213 m_serializedPosition = grppos;
214 302
215 m_basePosition += offset; 303 Vector3 grppos = grp.AbsolutePosition;
216 m_currentFrame.Position += offset; 304 Vector3 offset = grppos - m_serializedPosition;
305 // avoid doing it more than once
306 // current this will happen draging a prim to other region
307 m_serializedPosition = grppos;
217 308
218 m_nextPosition += offset; 309 m_basePosition += offset;
310 m_currentFrame.Position += offset;
219 311
220 for (int i = 0; i < m_frames.Count; i++) 312 m_nextPosition += offset;
221 {
222 Keyframe k = m_frames[i];
223 k.Position += offset;
224 m_frames[i]=k;
225 }
226 313
227 if (m_running) 314 for (int i = 0; i < m_frames.Count; i++)
228 Start(); 315 {
316 Keyframe k = m_frames[i];
317 k.Position += offset;
318 m_frames[i]=k;
229 } 319 }
320
321 if (m_running)
322 Start();
230 } 323 }
231 324
232 public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data) 325 public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data)
@@ -239,11 +332,10 @@ namespace OpenSim.Region.Framework.Scenes
239 { 332 {
240 m_basePosition = grp.AbsolutePosition; 333 m_basePosition = grp.AbsolutePosition;
241 m_baseRotation = grp.GroupRotation; 334 m_baseRotation = grp.GroupRotation;
335 m_scene = grp.Scene;
242 } 336 }
243 337
244 m_onTimerLock = new object();
245 m_timerStopped = true; 338 m_timerStopped = true;
246 m_inOnTimer = false;
247 m_isCrossing = false; 339 m_isCrossing = false;
248 m_waitingCrossing = false; 340 m_waitingCrossing = false;
249 } 341 }
@@ -260,6 +352,7 @@ namespace OpenSim.Region.Framework.Scenes
260 KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data); 352 KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data);
261 353
262 newmotion.m_group = newgrp; 354 newmotion.m_group = newgrp;
355 newmotion.m_scene = newgrp.Scene;
263 356
264 if (m_keyframes != null) 357 if (m_keyframes != null)
265 { 358 {
@@ -296,7 +389,7 @@ namespace OpenSim.Region.Framework.Scenes
296 public void Delete() 389 public void Delete()
297 { 390 {
298 m_running = false; 391 m_running = false;
299 RemoveTimer(); 392 StopTimer();
300 m_isCrossing = false; 393 m_isCrossing = false;
301 m_waitingCrossing = false; 394 m_waitingCrossing = false;
302 m_frames.Clear(); 395 m_frames.Clear();
@@ -309,27 +402,13 @@ namespace OpenSim.Region.Framework.Scenes
309 m_waitingCrossing = false; 402 m_waitingCrossing = false;
310 if (m_keyframes != null && m_group != null && m_keyframes.Length > 0) 403 if (m_keyframes != null && m_group != null && m_keyframes.Length > 0)
311 { 404 {
312 if (m_timer == null)
313 {
314 m_timer = new Timer();
315 m_timer.Interval = timerInterval;
316 m_timer.AutoReset = true;
317 m_timer.Elapsed += OnTimer;
318 }
319 else
320 {
321 StopTimer();
322 m_timer.Interval = timerInterval;
323 }
324
325 m_inOnTimer = false;
326 StartTimer(); 405 StartTimer();
327 m_running = true; 406 m_running = true;
328 } 407 }
329 else 408 else
330 { 409 {
331 m_running = false; 410 m_running = false;
332 RemoveTimer(); 411 StopTimer();
333 } 412 }
334 } 413 }
335 414
@@ -339,7 +418,7 @@ namespace OpenSim.Region.Framework.Scenes
339 m_isCrossing = false; 418 m_isCrossing = false;
340 m_waitingCrossing = false; 419 m_waitingCrossing = false;
341 420
342 RemoveTimer(); 421 StopTimer();
343 422
344 m_basePosition = m_group.AbsolutePosition; 423 m_basePosition = m_group.AbsolutePosition;
345 m_baseRotation = m_group.GroupRotation; 424 m_baseRotation = m_group.GroupRotation;
@@ -354,7 +433,7 @@ namespace OpenSim.Region.Framework.Scenes
354 public void Pause() 433 public void Pause()
355 { 434 {
356 m_running = false; 435 m_running = false;
357 RemoveTimer(); 436 StopTimer();
358 437
359 m_group.RootPart.Velocity = Vector3.Zero; 438 m_group.RootPart.Velocity = Vector3.Zero;
360 m_group.RootPart.AngularVelocity = Vector3.Zero; 439 m_group.RootPart.AngularVelocity = Vector3.Zero;
@@ -377,15 +456,11 @@ namespace OpenSim.Region.Framework.Scenes
377 456
378 int start = 0; 457 int start = 0;
379 int end = m_keyframes.Length; 458 int end = m_keyframes.Length;
380// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
381// end = m_keyframes.Length - 1;
382 459
383 if (direction < 0) 460 if (direction < 0)
384 { 461 {
385 start = m_keyframes.Length - 1; 462 start = m_keyframes.Length - 1;
386 end = -1; 463 end = -1;
387// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
388// end = 0;
389 } 464 }
390 465
391 for (int i = start; i != end ; i += direction) 466 for (int i = start; i != end ; i += direction)
@@ -463,189 +538,172 @@ namespace OpenSim.Region.Framework.Scenes
463 } 538 }
464 } 539 }
465 540
466 protected void OnTimer(object sender, ElapsedEventArgs e) 541 public void OnTimer(double tickDuration)
467 { 542 {
468 if (m_timerStopped) // trap events still in air even after a timer.stop 543 if (m_skipLoops > 0)
469 return;
470
471 if (m_inOnTimer) // don't let overruns to happen
472 { 544 {
473 m_log.Warn("[KeyFrame]: timer overrun"); 545 m_skipLoops--;
474 return; 546 return;
475 } 547 }
476 548
549 if (m_timerStopped) // trap events still in air even after a timer.stop
550 return;
551
477 if (m_group == null) 552 if (m_group == null)
478 return; 553 return;
479 554
480 lock (m_onTimerLock) 555 bool update = false;
481 {
482 556
483 m_inOnTimer = true; 557 if (m_selected)
558 {
559 if (m_group.RootPart.Velocity != Vector3.Zero)
560 {
561 m_group.RootPart.Velocity = Vector3.Zero;
562 m_group.SendGroupRootTerseUpdate();
484 563
485 bool update = false; 564 }
565 return;
566 }
486 567
487 try 568 if (m_isCrossing)
569 {
570 // if crossing and timer running then cross failed
571 // wait some time then
572 // retry to set the position that evtually caused the outbound
573 // if still outside region this will call startCrossing below
574 m_isCrossing = false;
575 m_group.AbsolutePosition = m_nextPosition;
576 if (!m_isCrossing)
488 { 577 {
489 if (m_selected) 578 StopTimer();
490 { 579 StartTimer();
491 if (m_group.RootPart.Velocity != Vector3.Zero) 580 }
492 { 581 return;
493 m_group.RootPart.Velocity = Vector3.Zero; 582 }
494 m_group.SendGroupRootTerseUpdate();
495// m_group.RootPart.ScheduleTerseUpdate();
496 583
497 } 584 if (m_frames.Count == 0)
498 m_inOnTimer = false; 585 {
499 return; 586 GetNextList();
500 }
501 587
502 if (m_isCrossing) 588 if (m_frames.Count == 0)
503 { 589 {
504 // if crossing and timer running then cross failed 590 Stop();
505 // wait some time then 591 Scene scene = m_group.Scene;
506 // retry to set the position that evtually caused the outbound
507 // if still outside region this will call startCrossing below
508 m_isCrossing = false;
509 m_group.AbsolutePosition = m_nextPosition;
510 if (!m_isCrossing)
511 {
512 StopTimer();
513 m_timer.Interval = timerInterval;
514 StartTimer();
515 }
516 m_inOnTimer = false;
517 return;
518 }
519 592
520 if (m_frames.Count == 0) 593 IScriptModule[] scriptModules = scene.RequestModuleInterfaces<IScriptModule>();
594 foreach (IScriptModule m in scriptModules)
521 { 595 {
522 GetNextList(); 596 if (m == null)
597 continue;
598 m.PostObjectEvent(m_group.RootPart.UUID, "moving_end", new object[0]);
599 }
523 600
524 if (m_frames.Count == 0) 601 return;
525 { 602 }
526 Stop();
527 m_inOnTimer = false;
528 return;
529 }
530 603
531 m_currentFrame = m_frames[0]; 604 m_currentFrame = m_frames[0];
532 m_currentFrame.TimeMS += (int)timerInterval; 605 m_currentFrame.TimeMS += (int)tickDuration;
533 606
534 //force a update on a keyframe transition 607 //force a update on a keyframe transition
535 update = true; 608 update = true;
536 } 609 }
537 610
538 m_currentFrame.TimeMS -= (int)timerInterval; 611 m_currentFrame.TimeMS -= (int)tickDuration;
539 612
540 // Do the frame processing 613 // Do the frame processing
541 double steps = (double)m_currentFrame.TimeMS / timerInterval; 614 double steps = (double)m_currentFrame.TimeMS / tickDuration;
542 615
543 if (steps <= 0.0) 616 if (steps <= 0.0)
544 { 617 {
545 m_group.RootPart.Velocity = Vector3.Zero; 618 m_group.RootPart.Velocity = Vector3.Zero;
546 m_group.RootPart.AngularVelocity = Vector3.Zero; 619 m_group.RootPart.AngularVelocity = Vector3.Zero;
547 620
548 m_nextPosition = (Vector3)m_currentFrame.Position; 621 m_nextPosition = (Vector3)m_currentFrame.Position;
549 m_group.AbsolutePosition = m_nextPosition; 622 m_group.AbsolutePosition = m_nextPosition;
550 623
551 // we are sending imediate updates, no doing force a extra terseUpdate 624 // we are sending imediate updates, no doing force a extra terseUpdate
552// m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); 625 // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
553 626
554 m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; 627 m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation;
555 m_frames.RemoveAt(0); 628 m_frames.RemoveAt(0);
556 if (m_frames.Count > 0) 629 if (m_frames.Count > 0)
557 m_currentFrame = m_frames[0]; 630 m_currentFrame = m_frames[0];
558 631
559 update = true; 632 update = true;
560 } 633 }
561 else 634 else
562 { 635 {
563 float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; 636 float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
564 637
565 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; 638 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
566 Vector3 motionThisFrame = v / (float)steps; 639 Vector3 motionThisFrame = v / (float)steps;
567 v = v * 1000 / m_currentFrame.TimeMS; 640 v = v * 1000 / m_currentFrame.TimeMS;
568 641
569 if (Vector3.Mag(motionThisFrame) >= 0.05f) 642 if (Vector3.Mag(motionThisFrame) >= 0.05f)
570 { 643 {
571 // m_group.AbsolutePosition += motionThisFrame; 644 // m_group.AbsolutePosition += motionThisFrame;
572 m_nextPosition = m_group.AbsolutePosition + motionThisFrame; 645 m_nextPosition = m_group.AbsolutePosition + motionThisFrame;
573 m_group.AbsolutePosition = m_nextPosition; 646 m_group.AbsolutePosition = m_nextPosition;
574 647
575 m_group.RootPart.Velocity = v; 648 m_group.RootPart.Velocity = v;
576 update = true; 649 update = true;
577 } 650 }
578 651
579 if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) 652 if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation)
580 { 653 {
581 Quaternion current = m_group.GroupRotation; 654 Quaternion current = m_group.GroupRotation;
582 655
583 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); 656 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete);
584 step.Normalize(); 657 step.Normalize();
585/* use simpler change detection 658/* use simpler change detection
586 * float angle = 0; 659* float angle = 0;
587
588 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
589 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
590 float aa_bb = aa * bb;
591
592 if (aa_bb == 0)
593 {
594 angle = 0;
595 }
596 else
597 {
598 float ab = current.X * step.X +
599 current.Y * step.Y +
600 current.Z * step.Z +
601 current.W * step.W;
602 float q = (ab * ab) / aa_bb;
603
604 if (q > 1.0f)
605 {
606 angle = 0;
607 }
608 else
609 {
610 angle = (float)Math.Acos(2 * q - 1);
611 }
612 }
613
614 if (angle > 0.01f)
615 */
616 if(Math.Abs(step.X - current.X) > 0.001f
617 || Math.Abs(step.Y - current.Y) > 0.001f
618 || Math.Abs(step.Z - current.Z) > 0.001f)
619 // assuming w is a dependente var
620 660
621 { 661 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
622// m_group.UpdateGroupRotationR(step); 662 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
623 m_group.RootPart.RotationOffset = step; 663 float aa_bb = aa * bb;
624 664
625 //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); 665 if (aa_bb == 0)
626 update = true; 666 {
627 } 667 angle = 0;
668 }
669 else
670 {
671 float ab = current.X * step.X +
672 current.Y * step.Y +
673 current.Z * step.Z +
674 current.W * step.W;
675 float q = (ab * ab) / aa_bb;
676
677 if (q > 1.0f)
678 {
679 angle = 0;
680 }
681 else
682 {
683 angle = (float)Math.Acos(2 * q - 1);
628 } 684 }
629 } 685 }
630 686
631 if (update) 687 if (angle > 0.01f)
632 m_group.SendGroupRootTerseUpdate(); 688*/
633// m_group.RootPart.ScheduleTerseUpdate(); 689 if(Math.Abs(step.X - current.X) > 0.001f
690 || Math.Abs(step.Y - current.Y) > 0.001f
691 || Math.Abs(step.Z - current.Z) > 0.001f)
692 // assuming w is a dependente var
634 693
694 {
695// m_group.UpdateGroupRotationR(step);
696 m_group.RootPart.RotationOffset = step;
635 697
698 //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2);
699 update = true;
700 }
636 } 701 }
637 catch ( Exception ex) 702 }
638 {
639 // still happening sometimes
640 // lets try to see where
641 m_log.Warn("[KeyFrame]: timer overrun" + ex.Message);
642 }
643 703
644 finally 704 if (update)
645 { 705 {
646 // make sure we do not let this frozen 706 m_group.SendGroupRootTerseUpdate();
647 m_inOnTimer = false;
648 }
649 } 707 }
650 } 708 }
651 709
@@ -677,7 +735,7 @@ namespace OpenSim.Region.Framework.Scenes
677 m_isCrossing = true; 735 m_isCrossing = true;
678 m_waitingCrossing = true; 736 m_waitingCrossing = true;
679 737
680// to remove / retune to smoth crossings 738 // to remove / retune to smoth crossings
681 if (m_group.RootPart.Velocity != Vector3.Zero) 739 if (m_group.RootPart.Velocity != Vector3.Zero)
682 { 740 {
683 m_group.RootPart.Velocity = Vector3.Zero; 741 m_group.RootPart.Velocity = Vector3.Zero;
@@ -696,9 +754,10 @@ namespace OpenSim.Region.Framework.Scenes
696 m_group.SendGroupRootTerseUpdate(); 754 m_group.SendGroupRootTerseUpdate();
697// m_group.RootPart.ScheduleTerseUpdate(); 755// m_group.RootPart.ScheduleTerseUpdate();
698 756
699 if (m_running && m_timer != null) 757 if (m_running)
700 { 758 {
701 m_timer.Interval = 60000; 759 StopTimer();
760 m_skipLoops = 1200; // 60 seconds
702 StartTimer(); 761 StartTimer();
703 } 762 }
704 } 763 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index c9d1205..4130029 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -401,17 +401,17 @@ namespace OpenSim.Region.Framework.Scenes
401 if (item.Owner != remoteClient.AgentId) 401 if (item.Owner != remoteClient.AgentId)
402 return; 402 return;
403 403
404 if (UUID.Zero == transactionID) 404 item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
405 { 405 item.Name = itemUpd.Name;
406 item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255); 406 item.Description = itemUpd.Description;
407 item.Name = itemUpd.Name;
408 item.Description = itemUpd.Description;
409 407
410// m_log.DebugFormat( 408// m_log.DebugFormat(
411// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}", 409// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
412// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags, 410// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
413// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions); 411// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
414 412
413 if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid
414 {
415 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) 415 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
416 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; 416 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
417 item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; 417 item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
@@ -446,7 +446,8 @@ namespace OpenSim.Region.Framework.Scenes
446 446
447 InventoryService.UpdateItem(item); 447 InventoryService.UpdateItem(item);
448 } 448 }
449 else 449
450 if (UUID.Zero != transactionID)
450 { 451 {
451 if (AgentTransactionsModule != null) 452 if (AgentTransactionsModule != null)
452 { 453 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index e3bc8c7..2e64819 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2769,8 +2769,6 @@ namespace OpenSim.Region.Framework.Scenes
2769 2769
2770 if (newPosition != Vector3.Zero) 2770 if (newPosition != Vector3.Zero)
2771 newObject.RootPart.GroupPosition = newPosition; 2771 newObject.RootPart.GroupPosition = newPosition;
2772 if (newObject.RootPart.KeyframeMotion != null)
2773 newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2774 2772
2775 if (!AddSceneObject(newObject)) 2773 if (!AddSceneObject(newObject))
2776 { 2774 {
@@ -2798,6 +2796,9 @@ namespace OpenSim.Region.Framework.Scenes
2798 // before we restart the scripts, or else some functions won't work. 2796 // before we restart the scripts, or else some functions won't work.
2799 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); 2797 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2800 newObject.ResumeScripts(); 2798 newObject.ResumeScripts();
2799
2800 if (newObject.RootPart.KeyframeMotion != null)
2801 newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2801 } 2802 }
2802 2803
2803 // Do this as late as possible so that listeners have full access to the incoming object 2804 // Do this as late as possible so that listeners have full access to the incoming object
@@ -2865,7 +2866,7 @@ namespace OpenSim.Region.Framework.Scenes
2865 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2866 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2866 2867
2867 if (AttachmentsModule != null) 2868 if (AttachmentsModule != null)
2868 AttachmentsModule.AttachObject(sp, grp, 0, false, false, false); 2869 AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true);
2869 } 2870 }
2870 else 2871 else
2871 { 2872 {
@@ -2970,6 +2971,13 @@ namespace OpenSim.Region.Framework.Scenes
2970 SubscribeToClientEvents(client); 2971 SubscribeToClientEvents(client);
2971 2972
2972 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); 2973 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2974 InventoryFolderBase cof = InventoryService.GetFolderForType(client.AgentId, (AssetType)46);
2975 if (cof == null)
2976 sp.COF = UUID.Zero;
2977 else
2978 sp.COF = cof.ID;
2979
2980 m_log.DebugFormat("[SCENE]: COF for {0} is {1}", client.AgentId, sp.COF);
2973 m_eventManager.TriggerOnNewPresence(sp); 2981 m_eventManager.TriggerOnNewPresence(sp);
2974 2982
2975 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; 2983 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
@@ -3615,7 +3623,7 @@ namespace OpenSim.Region.Framework.Scenes
3615 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3623 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3616 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3624 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3617 if (closeChildAgents && CapsModule != null) 3625 if (closeChildAgents && CapsModule != null)
3618 CapsModule.RemoveCaps(agentID); 3626 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
3619 3627
3620// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3628// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3621// // this method is doing is HORRIBLE!!! 3629// // this method is doing is HORRIBLE!!!
@@ -3846,20 +3854,36 @@ namespace OpenSim.Region.Framework.Scenes
3846 return false; 3854 return false;
3847 } 3855 }
3848 3856
3849
3850 ScenePresence sp = GetScenePresence(agent.AgentID); 3857 ScenePresence sp = GetScenePresence(agent.AgentID);
3851 3858
3852 if (sp != null && !sp.IsChildAgent) 3859 // If we have noo presence here or if that presence is a zombie root
3860 // presence that will be kicled, we need a new CAPS object.
3861 if (sp == null || (sp != null && !sp.IsChildAgent))
3853 { 3862 {
3854 // We have a zombie from a crashed session. 3863 if (CapsModule != null)
3855 // Or the same user is trying to be root twice here, won't work. 3864 {
3856 // Kill it. 3865 lock (agent)
3857 m_log.WarnFormat( 3866 {
3858 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3867 CapsModule.SetAgentCapsSeeds(agent);
3859 sp.Name, sp.UUID, RegionInfo.RegionName); 3868 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
3869 }
3870 }
3871 }
3860 3872
3861 sp.ControllingClient.Close(true, true); 3873 if (sp != null)
3862 sp = null; 3874 {
3875 if (!sp.IsChildAgent)
3876 {
3877 // We have a zombie from a crashed session.
3878 // Or the same user is trying to be root twice here, won't work.
3879 // Kill it.
3880 m_log.WarnFormat(
3881 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3882 sp.Name, sp.UUID, RegionInfo.RegionName);
3883
3884 sp.ControllingClient.Close(true, true);
3885 sp = null;
3886 }
3863 } 3887 }
3864 3888
3865 lock (agent) 3889 lock (agent)
@@ -3900,7 +3924,9 @@ namespace OpenSim.Region.Framework.Scenes
3900 if (vialogin || (!m_seeIntoBannedRegion)) 3924 if (vialogin || (!m_seeIntoBannedRegion))
3901 { 3925 {
3902 if (!AuthorizeUser(agent, out reason)) 3926 if (!AuthorizeUser(agent, out reason))
3927 {
3903 return false; 3928 return false;
3929 }
3904 } 3930 }
3905 } 3931 }
3906 catch (Exception e) 3932 catch (Exception e)
@@ -3915,11 +3941,6 @@ namespace OpenSim.Region.Framework.Scenes
3915 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 3941 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3916 agent.AgentID, agent.circuitcode); 3942 agent.AgentID, agent.circuitcode);
3917 3943
3918 if (CapsModule != null)
3919 {
3920 CapsModule.SetAgentCapsSeeds(agent);
3921 CapsModule.CreateCaps(agent.AgentID);
3922 }
3923 } 3944 }
3924 else 3945 else
3925 { 3946 {
@@ -3945,6 +3966,11 @@ namespace OpenSim.Region.Framework.Scenes
3945 agent.teleportFlags = teleportFlags; 3966 agent.teleportFlags = teleportFlags;
3946 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3967 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
3947 3968
3969 if (CapsModule != null)
3970 {
3971 CapsModule.ActivateCaps(agent.circuitcode);
3972 }
3973
3948 if (vialogin) 3974 if (vialogin)
3949 { 3975 {
3950// CleanDroppedAttachments(); 3976// CleanDroppedAttachments();
@@ -5122,7 +5148,7 @@ namespace OpenSim.Region.Framework.Scenes
5122 { 5148 {
5123 if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 5149 if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
5124 { 5150 {
5125 if (grp.RootPart.Expires <= DateTime.Now) 5151 if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now)
5126 DeleteSceneObject(grp, false); 5152 DeleteSceneObject(grp, false);
5127 } 5153 }
5128 } 5154 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 8528edc..20a6626 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1689,6 +1689,10 @@ namespace OpenSim.Region.Framework.Scenes
1689 1689
1690 if (ParentGroup != null) 1690 if (ParentGroup != null)
1691 ParentGroup.HasGroupChanged = true; 1691 ParentGroup.HasGroupChanged = true;
1692
1693 PhysicsActor pa = PhysActor;
1694 if (pa != null)
1695 pa.Density = Density;
1692 } 1696 }
1693 } 1697 }
1694 1698
@@ -1708,6 +1712,9 @@ namespace OpenSim.Region.Framework.Scenes
1708 if (ParentGroup != null) 1712 if (ParentGroup != null)
1709 ParentGroup.HasGroupChanged = true; 1713 ParentGroup.HasGroupChanged = true;
1710 1714
1715 PhysicsActor pa = PhysActor;
1716 if (pa != null)
1717 pa.GravModifier = GravityModifier;
1711 } 1718 }
1712 } 1719 }
1713 1720
@@ -1726,10 +1733,14 @@ namespace OpenSim.Region.Framework.Scenes
1726 1733
1727 if (ParentGroup != null) 1734 if (ParentGroup != null)
1728 ParentGroup.HasGroupChanged = true; 1735 ParentGroup.HasGroupChanged = true;
1736
1737 PhysicsActor pa = PhysActor;
1738 if (pa != null)
1739 pa.Friction = Friction;
1729 } 1740 }
1730 } 1741 }
1731 1742
1732 public float Bounciness 1743 public float Restitution
1733 { 1744 {
1734 get { return m_bounce; } 1745 get { return m_bounce; }
1735 set 1746 set
@@ -1744,6 +1755,10 @@ namespace OpenSim.Region.Framework.Scenes
1744 1755
1745 if (ParentGroup != null) 1756 if (ParentGroup != null)
1746 ParentGroup.HasGroupChanged = true; 1757 ParentGroup.HasGroupChanged = true;
1758
1759 PhysicsActor pa = PhysActor;
1760 if (pa != null)
1761 pa.Restitution = Restitution;
1747 } 1762 }
1748 } 1763 }
1749 1764
@@ -4493,8 +4508,8 @@ namespace OpenSim.Region.Framework.Scenes
4493 GravityModifier = physdata.GravitationModifier; 4508 GravityModifier = physdata.GravitationModifier;
4494 if(Friction != physdata.Friction) 4509 if(Friction != physdata.Friction)
4495 Friction = physdata.Friction; 4510 Friction = physdata.Friction;
4496 if(Bounciness != physdata.Bounce) 4511 if(Restitution != physdata.Bounce)
4497 Bounciness = physdata.Bounce; 4512 Restitution = physdata.Bounce;
4498 } 4513 }
4499 /// <summary> 4514 /// <summary>
4500 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4515 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
@@ -4657,6 +4672,11 @@ namespace OpenSim.Region.Framework.Scenes
4657 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4672 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
4658 pa.SetMaterial(Material); 4673 pa.SetMaterial(Material);
4659 4674
4675 pa.Density = Density;
4676 pa.GravModifier = GravityModifier;
4677 pa.Friction = Friction;
4678 pa.Restitution = Restitution;
4679
4660 if (VolumeDetectActive) // change if not the default only 4680 if (VolumeDetectActive) // change if not the default only
4661 pa.SetVolumeDetect(1); 4681 pa.SetVolumeDetect(1);
4662 4682
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a9195f7..230cb23 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -204,6 +204,11 @@ namespace OpenSim.Region.Framework.Scenes
204 204
205 private const int LAND_VELOCITYMAG_MAX = 12; 205 private const int LAND_VELOCITYMAG_MAX = 12;
206 206
207 private const float FLY_ROLL_MAX_RADIANS = 1.1f;
208
209 private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f;
210 private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
211
207 private float m_health = 100f; 212 private float m_health = 100f;
208 213
209 protected ulong crossingFromRegion; 214 protected ulong crossingFromRegion;
@@ -438,6 +443,8 @@ namespace OpenSim.Region.Framework.Scenes
438 get { return (IClientCore)ControllingClient; } 443 get { return (IClientCore)ControllingClient; }
439 } 444 }
440 445
446 public UUID COF { get; set; }
447
441// public Vector3 ParentPosition { get; set; } 448// public Vector3 ParentPosition { get; set; }
442 449
443 /// <summary> 450 /// <summary>
@@ -606,6 +613,14 @@ namespace OpenSim.Region.Framework.Scenes
606 } 613 }
607 } 614 }
608 615
616 // Used for limited viewer 'fake' user rotations.
617 private Vector3 m_AngularVelocity = Vector3.Zero;
618
619 public Vector3 AngularVelocity
620 {
621 get { return m_AngularVelocity; }
622 }
623
609 public bool IsChildAgent { get; set; } 624 public bool IsChildAgent { get; set; }
610 public bool IsLoggingIn { get; set; } 625 public bool IsLoggingIn { get; set; }
611 626
@@ -736,6 +751,8 @@ namespace OpenSim.Region.Framework.Scenes
736 751
737 #endregion 752 #endregion
738 753
754
755
739 #region Constructor(s) 756 #region Constructor(s)
740 757
741 public ScenePresence( 758 public ScenePresence(
@@ -1225,6 +1242,85 @@ namespace OpenSim.Region.Framework.Scenes
1225 ControllingClient.StopFlying(this); 1242 ControllingClient.StopFlying(this);
1226 } 1243 }
1227 1244
1245 /// <summary>
1246 /// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect.
1247 /// </summary>
1248 /// <param name="amount">Postive or negative roll amount in radians</param>
1249 private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown)
1250 {
1251
1252 float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
1253 m_AngularVelocity.Z = rollAmount;
1254
1255 // APPLY EXTRA consideration for flying up and flying down during this time.
1256 // if we're turning left
1257 if (amount > 0)
1258 {
1259
1260 // If we're at the max roll and pressing up, we want to swing BACK a bit
1261 // Automatically adds noise
1262 if (PressingUp)
1263 {
1264 if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f)
1265 m_AngularVelocity.Z -= 0.9f;
1266 }
1267 // If we're at the max roll and pressing down, we want to swing MORE a bit
1268 if (PressingDown)
1269 {
1270 if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f)
1271 m_AngularVelocity.Z += 0.6f;
1272 }
1273 }
1274 else // we're turning right.
1275 {
1276 // If we're at the max roll and pressing up, we want to swing BACK a bit
1277 // Automatically adds noise
1278 if (PressingUp)
1279 {
1280 if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS))
1281 m_AngularVelocity.Z += 0.6f;
1282 }
1283 // If we're at the max roll and pressing down, we want to swing MORE a bit
1284 if (PressingDown)
1285 {
1286 if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f)
1287 m_AngularVelocity.Z -= 0.6f;
1288 }
1289 }
1290 }
1291
1292 /// <summary>
1293 /// incrementally sets roll amount to zero
1294 /// </summary>
1295 /// <param name="amount">Positive roll amount in radians</param>
1296 /// <returns></returns>
1297 private float CalculateFlyingRollResetToZero(float amount)
1298 {
1299 const float rollMinRadians = 0f;
1300
1301 if (m_AngularVelocity.Z > 0)
1302 {
1303
1304 float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
1305 if (amount > leftOverToMin)
1306 return -leftOverToMin;
1307 else
1308 return -amount;
1309
1310 }
1311 else
1312 {
1313
1314 float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
1315 if (amount > leftOverToMin)
1316 return leftOverToMin;
1317 else
1318 return amount;
1319 }
1320 }
1321
1322
1323
1228 // neighbouring regions we have enabled a child agent in 1324 // neighbouring regions we have enabled a child agent in
1229 // holds the seed cap for the child agent in that region 1325 // holds the seed cap for the child agent in that region
1230 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); 1326 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
@@ -1430,17 +1526,42 @@ namespace OpenSim.Region.Framework.Scenes
1430 m_doingCamRayCast = false; 1526 m_doingCamRayCast = false;
1431 if (hitYN && localid != LocalId) 1527 if (hitYN && localid != LocalId)
1432 { 1528 {
1433 CameraConstraintActive = true; 1529 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1434 pNormal.X = (float)Math.Round(pNormal.X, 2); 1530 bool IsPrim = group != null;
1435 pNormal.Y = (float)Math.Round(pNormal.Y, 2); 1531 if (IsPrim)
1436 pNormal.Z = (float)Math.Round(pNormal.Z, 2); 1532 {
1437 pNormal.Normalize(); 1533 SceneObjectPart part = group.GetPart(localid);
1438 collisionPoint.X = (float)Math.Round(collisionPoint.X, 1); 1534 if (part != null && !part.VolumeDetectActive)
1439 collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1); 1535 {
1440 collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1); 1536 CameraConstraintActive = true;
1441 1537 pNormal.X = (float) Math.Round(pNormal.X, 2);
1442 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal)); 1538 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1443 UpdateCameraCollisionPlane(plane); 1539 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1540 pNormal.Normalize();
1541 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1542 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1543 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1544
1545 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1546 Vector3.Dot(collisionPoint, pNormal));
1547 UpdateCameraCollisionPlane(plane);
1548 }
1549 }
1550 else
1551 {
1552 CameraConstraintActive = true;
1553 pNormal.X = (float) Math.Round(pNormal.X, 2);
1554 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1555 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1556 pNormal.Normalize();
1557 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1558 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1559 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1560
1561 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1562 Vector3.Dot(collisionPoint, pNormal));
1563 UpdateCameraCollisionPlane(plane);
1564 }
1444 } 1565 }
1445 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1566 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1446 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1567 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
@@ -1741,6 +1862,33 @@ namespace OpenSim.Region.Framework.Scenes
1741 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || 1862 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1742 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 1863 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1743 1864
1865
1866 //m_log.Debug("[CONTROL]: " +flags);
1867 // Applies a satisfying roll effect to the avatar when flying.
1868 if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0))
1869 {
1870
1871 ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
1872
1873
1874 }
1875 else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) &&
1876 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0))
1877 {
1878 ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
1879
1880
1881 }
1882 else
1883 {
1884 if (m_AngularVelocity.Z != 0)
1885 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
1886
1887 }
1888
1889
1890
1891
1744 if (Flying && IsColliding && controlland) 1892 if (Flying && IsColliding && controlland)
1745 { 1893 {
1746 // nesting this check because LengthSquared() is expensive and we don't 1894 // nesting this check because LengthSquared() is expensive and we don't
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 123c158..2984782 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -633,7 +633,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
633 633
634 private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader) 634 private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader)
635 { 635 {
636 obj.Bounciness = reader.ReadElementContentAsFloat("Bounce", String.Empty); 636 obj.Restitution = reader.ReadElementContentAsFloat("Bounce", String.Empty);
637 } 637 }
638 638
639 private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader) 639 private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader)
@@ -1363,8 +1363,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1363 writer.WriteElementString("Density", sop.Density.ToString().ToLower()); 1363 writer.WriteElementString("Density", sop.Density.ToString().ToLower());
1364 if (sop.Friction != 0.6f) 1364 if (sop.Friction != 0.6f)
1365 writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); 1365 writer.WriteElementString("Friction", sop.Friction.ToString().ToLower());
1366 if (sop.Bounciness != 0.5f) 1366 if (sop.Restitution != 0.5f)
1367 writer.WriteElementString("Bounce", sop.Bounciness.ToString().ToLower()); 1367 writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower());
1368 if (sop.GravityModifier != 1.0f) 1368 if (sop.GravityModifier != 1.0f)
1369 writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); 1369 writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower());
1370 WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset()); 1370 WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset());