aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/KeyframeMotion.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/KeyframeMotion.cs280
1 files changed, 164 insertions, 116 deletions
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
index bbf3b51..cdd8d2d 100644
--- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
+++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
@@ -292,14 +292,17 @@ namespace OpenSim.Region.Framework.Scenes
292 292
293 private void StartTimer() 293 private void StartTimer()
294 { 294 {
295 KeyframeTimer.Add(this); 295 lock (m_frames)
296 m_timerStopped = false; 296 {
297 KeyframeTimer.Add(this);
298 m_timerStopped = false;
299 }
297 } 300 }
298 301
299 private void StopTimer() 302 private void StopTimer()
300 { 303 {
301 m_timerStopped = true; 304 lock (m_frames)
302 KeyframeTimer.Remove(this); 305 m_timerStopped = true;
303 } 306 }
304 307
305 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) 308 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data)
@@ -348,24 +351,26 @@ namespace OpenSim.Region.Framework.Scenes
348 m_group = grp; 351 m_group = grp;
349 m_scene = grp.Scene; 352 m_scene = grp.Scene;
350 353
351 Vector3 grppos = grp.AbsolutePosition;
352 Vector3 offset = grppos - m_serializedPosition;
353 // avoid doing it more than once
354 // current this will happen dragging a prim to other region
355 m_serializedPosition = grppos;
356 354
357 m_basePosition += offset; 355 lock (m_frames)
358 m_nextPosition += offset;
359
360 m_currentFrame.StartPosition += offset;
361 m_currentFrame.Position += offset;
362
363 for (int i = 0; i < m_frames.Count; i++)
364 { 356 {
365 Keyframe k = m_frames[i]; 357 Vector3 grppos = grp.AbsolutePosition;
366 k.StartPosition += offset; 358 Vector3 offset = grppos - m_serializedPosition;
367 k.Position += offset; 359 // avoid doing it more than once
368 m_frames[i]=k; 360 // current this will happen draging a prim to other region
361 m_serializedPosition = grppos;
362
363 m_basePosition += offset;
364 m_currentFrame.Position += offset;
365
366 m_nextPosition += offset;
367
368 for (int i = 0; i < m_frames.Count; i++)
369 {
370 Keyframe k = m_frames[i];
371 k.Position += offset;
372 m_frames[i] = k;
373 }
369 } 374 }
370 375
371 if (m_running) 376 if (m_running)
@@ -410,25 +415,28 @@ namespace OpenSim.Region.Framework.Scenes
410 m_keyframes.CopyTo(newmotion.m_keyframes, 0); 415 m_keyframes.CopyTo(newmotion.m_keyframes, 0);
411 } 416 }
412 417
413 newmotion.m_frames = new List<Keyframe>(m_frames); 418 lock (m_frames)
419 {
420 newmotion.m_frames = new List<Keyframe>(m_frames);
414 421
415 newmotion.m_basePosition = m_basePosition; 422 newmotion.m_basePosition = m_basePosition;
416 newmotion.m_baseRotation = m_baseRotation; 423 newmotion.m_baseRotation = m_baseRotation;
417 424
418 if (m_selected) 425 if (m_selected)
419 newmotion.m_serializedPosition = m_serializedPosition;
420 else
421 {
422 if (m_group != null)
423 newmotion.m_serializedPosition = m_group.AbsolutePosition;
424 else
425 newmotion.m_serializedPosition = m_serializedPosition; 426 newmotion.m_serializedPosition = m_serializedPosition;
426 } 427 else
428 {
429 if (m_group != null)
430 newmotion.m_serializedPosition = m_group.AbsolutePosition;
431 else
432 newmotion.m_serializedPosition = m_serializedPosition;
433 }
427 434
428 newmotion.m_currentFrame = m_currentFrame; 435 newmotion.m_currentFrame = m_currentFrame;
429 436
430 newmotion.m_iterations = m_iterations; 437 newmotion.m_iterations = m_iterations;
431 newmotion.m_running = m_running; 438 newmotion.m_running = m_running;
439 }
432 440
433 if (m_running && !m_waitingCrossing) 441 if (m_running && !m_waitingCrossing)
434 StartTimer(); 442 StartTimer();
@@ -458,19 +466,18 @@ namespace OpenSim.Region.Framework.Scenes
458 } 466 }
459 else 467 else
460 { 468 {
461 m_running = false;
462 StopTimer(); 469 StopTimer();
470 m_running = false;
463 } 471 }
464 } 472 }
465 473
466 public void Stop() 474 public void Stop()
467 { 475 {
476 StopTimer();
468 m_running = false; 477 m_running = false;
469 m_isCrossing = false; 478 m_isCrossing = false;
470 m_waitingCrossing = false; 479 m_waitingCrossing = false;
471 480
472 StopTimer();
473
474 m_basePosition = m_group.AbsolutePosition; 481 m_basePosition = m_group.AbsolutePosition;
475 m_baseRotation = m_group.GroupRotation; 482 m_baseRotation = m_group.GroupRotation;
476 483
@@ -483,14 +490,34 @@ namespace OpenSim.Region.Framework.Scenes
483 490
484 public void Pause() 491 public void Pause()
485 { 492 {
486 m_running = false;
487 StopTimer(); 493 StopTimer();
494 m_running = false;
488 495
489 m_group.RootPart.Velocity = Vector3.Zero; 496 m_group.RootPart.Velocity = Vector3.Zero;
490 m_group.RootPart.AngularVelocity = Vector3.Zero; 497 m_group.RootPart.AngularVelocity = Vector3.Zero;
491 m_group.SendGroupRootTerseUpdate(); 498 m_group.SendGroupRootTerseUpdate();
492// m_group.RootPart.ScheduleTerseUpdate(); 499// m_group.RootPart.ScheduleTerseUpdate();
500 }
493 501
502 public void Suspend()
503 {
504 lock (m_frames)
505 {
506 if (m_timerStopped)
507 return;
508 m_timerStopped = true;
509 }
510 }
511
512 public void Resume()
513 {
514 lock (m_frames)
515 {
516 if (!m_timerStopped)
517 return;
518 if (m_running && !m_waitingCrossing)
519 StartTimer();
520 }
494 } 521 }
495 522
496 private void GetNextList() 523 private void GetNextList()
@@ -581,6 +608,7 @@ namespace OpenSim.Region.Framework.Scenes
581 608
582 pos = (Vector3)k.Position; 609 pos = (Vector3)k.Position;
583 rot = (Quaternion)k.Rotation; 610 rot = (Quaternion)k.Rotation;
611
584 } 612 }
585 613
586 m_basePosition = pos; 614 m_basePosition = pos;
@@ -592,15 +620,41 @@ namespace OpenSim.Region.Framework.Scenes
592 620
593 public void OnTimer(double tickDuration) 621 public void OnTimer(double tickDuration)
594 { 622 {
623 if (!Monitor.TryEnter(m_frames))
624 return;
625 if (m_timerStopped)
626 KeyframeTimer.Remove(this);
627 else
628 DoOnTimer(tickDuration);
629 Monitor.Exit(m_frames);
630 }
631
632 private void Done()
633 {
634 KeyframeTimer.Remove(this);
635 m_timerStopped = true;
636 m_running = false;
637 m_isCrossing = false;
638 m_waitingCrossing = false;
639
640 m_basePosition = m_group.AbsolutePosition;
641 m_baseRotation = m_group.GroupRotation;
642
643 m_group.RootPart.Velocity = Vector3.Zero;
644 m_group.RootPart.AngularVelocity = Vector3.Zero;
645 m_group.SendGroupRootTerseUpdate();
646 // m_group.RootPart.ScheduleTerseUpdate();
647 m_frames.Clear();
648 }
649
650 private void DoOnTimer(double tickDuration)
651 {
595 if (m_skipLoops > 0) 652 if (m_skipLoops > 0)
596 { 653 {
597 m_skipLoops--; 654 m_skipLoops--;
598 return; 655 return;
599 } 656 }
600 657
601 if (m_timerStopped) // trap events still in air even after a timer.stop
602 return;
603
604 if (m_group == null) 658 if (m_group == null)
605 return; 659 return;
606 660
@@ -612,7 +666,6 @@ namespace OpenSim.Region.Framework.Scenes
612 { 666 {
613 m_group.RootPart.Velocity = Vector3.Zero; 667 m_group.RootPart.Velocity = Vector3.Zero;
614 m_group.SendGroupRootTerseUpdate(); 668 m_group.SendGroupRootTerseUpdate();
615
616 } 669 }
617 return; 670 return;
618 } 671 }
@@ -635,32 +688,22 @@ namespace OpenSim.Region.Framework.Scenes
635 688
636 if (m_frames.Count == 0) 689 if (m_frames.Count == 0)
637 { 690 {
638 if (!m_running) return; 691 lock (m_frames)
639
640 GetNextList();
641
642 if (m_frames.Count == 0)
643 { 692 {
644 Stop(); 693 GetNextList();
645// Scene scene = m_group.Scene;
646//
647// IScriptModule[] scriptModules = scene.RequestModuleInterfaces<IScriptModule>();
648// foreach (IScriptModule m in scriptModules)
649// {
650// if (m == null)
651// continue;
652// m.PostObjectEvent(m_group.RootPart.UUID, "moving_end", new object[0]);
653// }
654
655 m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
656
657 return;
658 }
659 694
660 m_currentFrame = m_frames[0]; 695 if (m_frames.Count == 0)
661 m_currentFrame.TimeMS += (int)tickDuration; 696 {
697 Done();
698 m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
699 return;
700 }
662 701
702 m_currentFrame = m_frames[0];
703 m_currentFrame.TimeMS += (int)tickDuration;
704 }
663 //force a update on a keyframe transition 705 //force a update on a keyframe transition
706 m_nextPosition = m_group.AbsolutePosition;
664 update = true; 707 update = true;
665 } 708 }
666 709
@@ -681,9 +724,13 @@ namespace OpenSim.Region.Framework.Scenes
681 // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); 724 // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
682 725
683 m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; 726 m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation;
684 m_frames.RemoveAt(0); 727
685 if (m_frames.Count > 0) 728 lock (m_frames)
686 m_currentFrame = m_frames[0]; 729 {
730 m_frames.RemoveAt(0);
731 if (m_frames.Count > 0)
732 m_currentFrame = m_frames[0];
733 }
687 734
688 update = true; 735 update = true;
689 } 736 }
@@ -692,17 +739,14 @@ namespace OpenSim.Region.Framework.Scenes
692 float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; 739 float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
693 bool lastStep = m_currentFrame.TimeMS <= tickDuration; 740 bool lastStep = m_currentFrame.TimeMS <= tickDuration;
694 741
695 Vector3 positionThisStep = m_currentFrame.StartPosition + (m_currentFrame.Position.Value - m_currentFrame.StartPosition) * completed; 742 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
696 Vector3 motionThisStep = positionThisStep - m_group.AbsolutePosition; 743 Vector3 motionThisFrame = v / (float)remainingSteps;
744 v = v * 1000 / m_currentFrame.TimeMS;
697 745
698 float mag = Vector3.Mag(motionThisStep); 746 m_nextPosition = m_group.AbsolutePosition + motionThisFrame;
699 747
700 if ((mag >= 0.02f) || lastStep) 748 if (Vector3.Mag(motionThisFrame) >= 0.05f)
701 {
702 m_nextPosition = m_group.AbsolutePosition + motionThisStep;
703 m_group.AbsolutePosition = m_nextPosition;
704 update = true; 749 update = true;
705 }
706 750
707 //int totalSteps = m_currentFrame.TimeTotal / (int)tickDuration; 751 //int totalSteps = m_currentFrame.TimeTotal / (int)tickDuration;
708 //m_log.DebugFormat("KeyframeMotion.OnTimer: step {0}/{1}, curPosition={2}, finalPosition={3}, motionThisStep={4} (scene {5})", 752 //m_log.DebugFormat("KeyframeMotion.OnTimer: step {0}/{1}, curPosition={2}, finalPosition={3}, motionThisStep={4} (scene {5})",
@@ -714,43 +758,41 @@ namespace OpenSim.Region.Framework.Scenes
714 758
715 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed); 759 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed);
716 step.Normalize(); 760 step.Normalize();
717/* use simpler change detection 761 /* use simpler change detection
718* float angle = 0; 762 * float angle = 0;
719 763
720 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; 764 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
721 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; 765 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
722 float aa_bb = aa * bb; 766 float aa_bb = aa * bb;
723 767
724 if (aa_bb == 0) 768 if (aa_bb == 0)
725 { 769 {
726 angle = 0; 770 angle = 0;
727 } 771 }
728 else 772 else
729 { 773 {
730 float ab = current.X * step.X + 774 float ab = current.X * step.X +
731 current.Y * step.Y + 775 current.Y * step.Y +
732 current.Z * step.Z + 776 current.Z * step.Z +
733 current.W * step.W; 777 current.W * step.W;
734 float q = (ab * ab) / aa_bb; 778 float q = (ab * ab) / aa_bb;
735 779
736 if (q > 1.0f) 780 if (q > 1.0f)
737 { 781 {
738 angle = 0; 782 angle = 0;
739 } 783 }
740 else 784 else
741 { 785 {
742 angle = (float)Math.Acos(2 * q - 1); 786 angle = (float)Math.Acos(2 * q - 1);
743 } 787 }
744 } 788 }
745 789
746 if (angle > 0.01f) 790 if (angle > 0.01f)
747*/ 791 */
748 if(Math.Abs(step.X - current.X) > 0.001f 792 if (Math.Abs(step.X - current.X) > 0.001f
749 || Math.Abs(step.Y - current.Y) > 0.001f 793 || Math.Abs(step.Y - current.Y) > 0.001f
750 || Math.Abs(step.Z - current.Z) > 0.001f 794 || Math.Abs(step.Z - current.Z) > 0.001f)
751 || lastStep) 795 // assuming w is a dependente var
752 // assuming w is a dependente var
753
754 { 796 {
755// m_group.UpdateGroupRotationR(step); 797// m_group.UpdateGroupRotationR(step);
756 m_group.RootPart.RotationOffset = step; 798 m_group.RootPart.RotationOffset = step;
@@ -763,25 +805,31 @@ namespace OpenSim.Region.Framework.Scenes
763 805
764 if (update) 806 if (update)
765 { 807 {
808 m_group.AbsolutePosition = m_nextPosition;
766 m_group.SendGroupRootTerseUpdate(); 809 m_group.SendGroupRootTerseUpdate();
767 } 810 }
768 } 811 }
769 812
770 public Byte[] Serialize() 813 public Byte[] Serialize()
771 { 814 {
815 bool timerWasStopped;
816 lock (m_frames)
817 {
818 timerWasStopped = m_timerStopped;
819 }
772 StopTimer(); 820 StopTimer();
773 821
774 SceneObjectGroup tmp = m_group; 822 SceneObjectGroup tmp = m_group;
775 m_group = null; 823 m_group = null;
776 if (!m_selected && tmp != null) 824
777 m_serializedPosition = tmp.AbsolutePosition;
778
779 using (MemoryStream ms = new MemoryStream()) 825 using (MemoryStream ms = new MemoryStream())
780 { 826 {
781 BinaryFormatter fmt = new BinaryFormatter(); 827 BinaryFormatter fmt = new BinaryFormatter();
828 if (!m_selected && tmp != null)
829 m_serializedPosition = tmp.AbsolutePosition;
782 fmt.Serialize(ms, this); 830 fmt.Serialize(ms, this);
783 m_group = tmp; 831 m_group = tmp;
784 if (m_running && !m_waitingCrossing) 832 if (!timerWasStopped && m_running && !m_waitingCrossing)
785 StartTimer(); 833 StartTimer();
786 834
787 return ms.ToArray(); 835 return ms.ToArray();