diff options
author | UbitUmarov | 2017-04-04 12:38:23 +0100 |
---|---|---|
committer | UbitUmarov | 2017-04-04 12:38:23 +0100 |
commit | 056b765fbc17b2702ca35c9211144db881f7b9e3 (patch) | |
tree | 96d071b24db54006379d23983ae75ee5775188e4 | |
parent | mantis 8140: fix objectTeleport rotation if stop TRUE (diff) | |
download | opensim-SC_OLD-056b765fbc17b2702ca35c9211144db881f7b9e3.zip opensim-SC_OLD-056b765fbc17b2702ca35c9211144db881f7b9e3.tar.gz opensim-SC_OLD-056b765fbc17b2702ca35c9211144db881f7b9e3.tar.bz2 opensim-SC_OLD-056b765fbc17b2702ca35c9211144db881f7b9e3.tar.xz |
mantis 8130: improve keyframes motion
-rw-r--r-- | OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 133 |
1 files changed, 63 insertions, 70 deletions
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index e4aa196..d81d8a2 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | |||
@@ -495,6 +495,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
495 | 495 | ||
496 | m_group.RootPart.Velocity = Vector3.Zero; | 496 | m_group.RootPart.Velocity = Vector3.Zero; |
497 | m_group.RootPart.AngularVelocity = Vector3.Zero; | 497 | m_group.RootPart.AngularVelocity = Vector3.Zero; |
498 | m_skippedUpdates = 1000; | ||
498 | m_group.SendGroupRootTerseUpdate(); | 499 | m_group.SendGroupRootTerseUpdate(); |
499 | // m_group.RootPart.ScheduleTerseUpdate(); | 500 | // m_group.RootPart.ScheduleTerseUpdate(); |
500 | } | 501 | } |
@@ -517,6 +518,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
517 | return; | 518 | return; |
518 | if (m_running && !m_waitingCrossing) | 519 | if (m_running && !m_waitingCrossing) |
519 | StartTimer(); | 520 | StartTimer(); |
521 | m_skippedUpdates = 1000; | ||
520 | } | 522 | } |
521 | } | 523 | } |
522 | 524 | ||
@@ -643,10 +645,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
643 | m_group.RootPart.Velocity = Vector3.Zero; | 645 | m_group.RootPart.Velocity = Vector3.Zero; |
644 | m_group.RootPart.AngularVelocity = Vector3.Zero; | 646 | m_group.RootPart.AngularVelocity = Vector3.Zero; |
645 | m_group.SendGroupRootTerseUpdate(); | 647 | m_group.SendGroupRootTerseUpdate(); |
646 | // m_group.RootPart.ScheduleTerseUpdate(); | 648 | |
647 | m_frames.Clear(); | 649 | m_frames.Clear(); |
648 | } | 650 | } |
649 | 651 | ||
652 | Vector3 m_lastPosUpdate; | ||
653 | Quaternion m_lastRotationUpdate; | ||
654 | Vector3 m_currentVel; | ||
655 | int m_skippedUpdates; | ||
656 | |||
650 | private void DoOnTimer(double tickDuration) | 657 | private void DoOnTimer(double tickDuration) |
651 | { | 658 | { |
652 | if (m_skipLoops > 0) | 659 | if (m_skipLoops > 0) |
@@ -665,6 +672,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
665 | if (m_group.RootPart.Velocity != Vector3.Zero) | 672 | if (m_group.RootPart.Velocity != Vector3.Zero) |
666 | { | 673 | { |
667 | m_group.RootPart.Velocity = Vector3.Zero; | 674 | m_group.RootPart.Velocity = Vector3.Zero; |
675 | m_skippedUpdates = 1000; | ||
668 | m_group.SendGroupRootTerseUpdate(); | 676 | m_group.SendGroupRootTerseUpdate(); |
669 | } | 677 | } |
670 | return; | 678 | return; |
@@ -677,7 +685,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
677 | // retry to set the position that evtually caused the outbound | 685 | // retry to set the position that evtually caused the outbound |
678 | // if still outside region this will call startCrossing below | 686 | // if still outside region this will call startCrossing below |
679 | m_isCrossing = false; | 687 | m_isCrossing = false; |
688 | m_skippedUpdates = 1000; | ||
680 | m_group.AbsolutePosition = m_nextPosition; | 689 | m_group.AbsolutePosition = m_nextPosition; |
690 | |||
681 | if (!m_isCrossing) | 691 | if (!m_isCrossing) |
682 | { | 692 | { |
683 | StopTimer(); | 693 | StopTimer(); |
@@ -700,10 +710,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
700 | } | 710 | } |
701 | 711 | ||
702 | m_currentFrame = m_frames[0]; | 712 | m_currentFrame = m_frames[0]; |
703 | m_currentFrame.TimeMS += (int)tickDuration; | ||
704 | } | 713 | } |
705 | //force a update on a keyframe transition | ||
706 | m_nextPosition = m_group.AbsolutePosition; | 714 | m_nextPosition = m_group.AbsolutePosition; |
715 | m_currentVel = (Vector3)m_currentFrame.Position - m_nextPosition; | ||
716 | m_currentVel /= (m_currentFrame.TimeMS * 0.001f); | ||
717 | |||
718 | m_currentFrame.TimeMS += (int)tickDuration; | ||
707 | update = true; | 719 | update = true; |
708 | } | 720 | } |
709 | 721 | ||
@@ -712,7 +724,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
712 | // Do the frame processing | 724 | // Do the frame processing |
713 | double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration; | 725 | double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration; |
714 | 726 | ||
715 | if (remainingSteps <= 0.0) | 727 | if (remainingSteps <= 1.0) |
716 | { | 728 | { |
717 | m_group.RootPart.Velocity = Vector3.Zero; | 729 | m_group.RootPart.Velocity = Vector3.Zero; |
718 | m_group.RootPart.AngularVelocity = Vector3.Zero; | 730 | m_group.RootPart.AngularVelocity = Vector3.Zero; |
@@ -720,92 +732,71 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | m_nextPosition = (Vector3)m_currentFrame.Position; | 732 | m_nextPosition = (Vector3)m_currentFrame.Position; |
721 | m_group.AbsolutePosition = m_nextPosition; | 733 | m_group.AbsolutePosition = m_nextPosition; |
722 | 734 | ||
723 | // we are sending imediate updates, no doing force a extra terseUpdate | ||
724 | // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); | ||
725 | |||
726 | m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; | 735 | m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; |
727 | 736 | ||
728 | lock (m_frames) | 737 | lock (m_frames) |
729 | { | 738 | { |
730 | m_frames.RemoveAt(0); | 739 | m_frames.RemoveAt(0); |
731 | if (m_frames.Count > 0) | 740 | if (m_frames.Count > 0) |
741 | { | ||
732 | m_currentFrame = m_frames[0]; | 742 | m_currentFrame = m_frames[0]; |
743 | m_currentVel = (Vector3)m_currentFrame.Position - m_nextPosition; | ||
744 | m_currentVel /= (m_currentFrame.TimeMS * 0.001f); | ||
745 | m_group.RootPart.Velocity = m_currentVel; | ||
746 | m_currentFrame.TimeMS += (int)tickDuration; | ||
747 | } | ||
748 | else | ||
749 | m_group.RootPart.Velocity = Vector3.Zero; | ||
733 | } | 750 | } |
734 | |||
735 | update = true; | 751 | update = true; |
736 | } | 752 | } |
737 | else | 753 | else |
738 | { | 754 | { |
739 | float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; | 755 | bool lastSteps = remainingSteps < 4; |
740 | bool lastStep = m_currentFrame.TimeMS <= tickDuration; | 756 | Vector3 currentPosition = m_group.AbsolutePosition; |
741 | 757 | Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition; | |
742 | Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; | 758 | motionThisFrame /= (float)remainingSteps; |
743 | Vector3 motionThisFrame = v / (float)remainingSteps; | 759 | |
744 | v = v * 1000 / m_currentFrame.TimeMS; | 760 | m_nextPosition = currentPosition + motionThisFrame; |
745 | 761 | ||
746 | m_nextPosition = m_group.AbsolutePosition + motionThisFrame; | 762 | Quaternion currentRotation = m_group.GroupRotation; |
747 | 763 | if ((Quaternion)m_currentFrame.Rotation != currentRotation) | |
748 | if (Vector3.Mag(motionThisFrame) >= 0.05f) | ||
749 | update = true; | ||
750 | |||
751 | //int totalSteps = m_currentFrame.TimeTotal / (int)tickDuration; | ||
752 | //m_log.DebugFormat("KeyframeMotion.OnTimer: step {0}/{1}, curPosition={2}, finalPosition={3}, motionThisStep={4} (scene {5})", | ||
753 | // totalSteps - remainingSteps + 1, totalSteps, m_group.AbsolutePosition, m_currentFrame.Position, motionThisStep, m_scene.RegionInfo.RegionName); | ||
754 | |||
755 | if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) | ||
756 | { | 764 | { |
757 | Quaternion current = m_group.GroupRotation; | 765 | float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; |
758 | |||
759 | Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed); | 766 | Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed); |
760 | step.Normalize(); | 767 | step.Normalize(); |
761 | /* use simpler change detection | 768 | m_group.RootPart.RotationOffset = step; |
762 | * float angle = 0; | 769 | if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f |
763 | 770 | || Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f | |
764 | float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; | 771 | || Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f) |
765 | float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; | ||
766 | float aa_bb = aa * bb; | ||
767 | |||
768 | if (aa_bb == 0) | ||
769 | { | ||
770 | angle = 0; | ||
771 | } | ||
772 | else | ||
773 | { | ||
774 | float ab = current.X * step.X + | ||
775 | current.Y * step.Y + | ||
776 | current.Z * step.Z + | ||
777 | current.W * step.W; | ||
778 | float q = (ab * ab) / aa_bb; | ||
779 | |||
780 | if (q > 1.0f) | ||
781 | { | ||
782 | angle = 0; | ||
783 | } | ||
784 | else | ||
785 | { | ||
786 | angle = (float)Math.Acos(2 * q - 1); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | if (angle > 0.01f) | ||
791 | */ | ||
792 | if (Math.Abs(step.X - current.X) > 0.001f | ||
793 | || Math.Abs(step.Y - current.Y) > 0.001f | ||
794 | || Math.Abs(step.Z - current.Z) > 0.001f) | ||
795 | // assuming w is a dependente var | ||
796 | { | ||
797 | // m_group.UpdateGroupRotationR(step); | ||
798 | m_group.RootPart.RotationOffset = step; | ||
799 | |||
800 | //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); | ||
801 | update = true; | 772 | update = true; |
802 | } | ||
803 | } | 773 | } |
804 | } | ||
805 | 774 | ||
806 | if (update) | ||
807 | { | ||
808 | m_group.AbsolutePosition = m_nextPosition; | 775 | m_group.AbsolutePosition = m_nextPosition; |
776 | if(lastSteps) | ||
777 | m_group.RootPart.Velocity = Vector3.Zero; | ||
778 | else | ||
779 | m_group.RootPart.Velocity = m_currentVel; | ||
780 | |||
781 | if(!update && ( | ||
782 | lastSteps || | ||
783 | m_skippedUpdates * tickDuration > 0.5 || | ||
784 | Math.Abs(m_nextPosition.X - currentPosition.X) > 5f || | ||
785 | Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f || | ||
786 | Math.Abs(m_nextPosition.Z - currentPosition.Z) > 5f | ||
787 | )) | ||
788 | { | ||
789 | update = true; | ||
790 | } | ||
791 | else | ||
792 | m_skippedUpdates++; | ||
793 | |||
794 | } | ||
795 | if(update) | ||
796 | { | ||
797 | m_lastPosUpdate = m_nextPosition; | ||
798 | m_lastRotationUpdate = m_group.GroupRotation; | ||
799 | m_skippedUpdates = 0; | ||
809 | m_group.SendGroupRootTerseUpdate(); | 800 | m_group.SendGroupRootTerseUpdate(); |
810 | } | 801 | } |
811 | } | 802 | } |
@@ -850,6 +841,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
850 | if (m_group.RootPart.Velocity != Vector3.Zero) | 841 | if (m_group.RootPart.Velocity != Vector3.Zero) |
851 | { | 842 | { |
852 | m_group.RootPart.Velocity = Vector3.Zero; | 843 | m_group.RootPart.Velocity = Vector3.Zero; |
844 | m_skippedUpdates = 1000; | ||
853 | m_group.SendGroupRootTerseUpdate(); | 845 | m_group.SendGroupRootTerseUpdate(); |
854 | // m_group.RootPart.ScheduleTerseUpdate(); | 846 | // m_group.RootPart.ScheduleTerseUpdate(); |
855 | } | 847 | } |
@@ -862,6 +854,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
862 | if (m_group != null) | 854 | if (m_group != null) |
863 | { | 855 | { |
864 | m_group.RootPart.Velocity = Vector3.Zero; | 856 | m_group.RootPart.Velocity = Vector3.Zero; |
857 | m_skippedUpdates = 1000; | ||
865 | m_group.SendGroupRootTerseUpdate(); | 858 | m_group.SendGroupRootTerseUpdate(); |
866 | // m_group.RootPart.ScheduleTerseUpdate(); | 859 | // m_group.RootPart.ScheduleTerseUpdate(); |
867 | 860 | ||