diff options
author | Robert Adams | 2013-09-04 07:56:59 -0700 |
---|---|---|
committer | Robert Adams | 2013-09-11 09:12:18 -0700 |
commit | 5827b6e1aabf2e19624faf0141b9611917fb84c5 (patch) | |
tree | 6b13ebc4d7840d5dcd04d4efeddfdbb933609620 /OpenSim/Region/Physics | |
parent | BulletSim: ability to specify groups of axis to modify in constraint paramete... (diff) | |
download | opensim-SC_OLD-5827b6e1aabf2e19624faf0141b9611917fb84c5.zip opensim-SC_OLD-5827b6e1aabf2e19624faf0141b9611917fb84c5.tar.gz opensim-SC_OLD-5827b6e1aabf2e19624faf0141b9611917fb84c5.tar.bz2 opensim-SC_OLD-5827b6e1aabf2e19624faf0141b9611917fb84c5.tar.xz |
BulletSim: add extended physics LSL constants for axis specification.
Add specific error warnings for mis-matched parameter types in extended
physics functions.
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs | 6 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | 89 |
2 files changed, 60 insertions, 35 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs index 432e5b2..652c94a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs | |||
@@ -63,7 +63,7 @@ public sealed class BSConstraintSpring : BSConstraint6Dof | |||
63 | 63 | ||
64 | public bool SetStiffness(int pIndex, float pStiffness) | 64 | public bool SetStiffness(int pIndex, float pStiffness) |
65 | { | 65 | { |
66 | PhysicsScene.DetailLog("{0},BSConstraintSpring.SetStiffness,obj1ID={1},obj2ID={2},indx={3},enable={4}", | 66 | PhysicsScene.DetailLog("{0},BSConstraintSpring.SetStiffness,obj1ID={1},obj2ID={2},indx={3},stiff={4}", |
67 | m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pStiffness); | 67 | m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pStiffness); |
68 | PhysicsScene.PE.SpringSetStiffness(m_constraint, pIndex, pStiffness); | 68 | PhysicsScene.PE.SpringSetStiffness(m_constraint, pIndex, pStiffness); |
69 | return true; | 69 | return true; |
@@ -71,7 +71,7 @@ public sealed class BSConstraintSpring : BSConstraint6Dof | |||
71 | 71 | ||
72 | public bool SetDamping(int pIndex, float pDamping) | 72 | public bool SetDamping(int pIndex, float pDamping) |
73 | { | 73 | { |
74 | PhysicsScene.DetailLog("{0},BSConstraintSpring.SetDamping,obj1ID={1},obj2ID={2},indx={3},enable={4}", | 74 | PhysicsScene.DetailLog("{0},BSConstraintSpring.SetDamping,obj1ID={1},obj2ID={2},indx={3},damp={4}", |
75 | m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pDamping); | 75 | m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pDamping); |
76 | PhysicsScene.PE.SpringSetDamping(m_constraint, pIndex, pDamping); | 76 | PhysicsScene.PE.SpringSetDamping(m_constraint, pIndex, pDamping); |
77 | return true; | 77 | return true; |
@@ -79,7 +79,7 @@ public sealed class BSConstraintSpring : BSConstraint6Dof | |||
79 | 79 | ||
80 | public bool SetEquilibriumPoint(int pIndex, float pEqPoint) | 80 | public bool SetEquilibriumPoint(int pIndex, float pEqPoint) |
81 | { | 81 | { |
82 | PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},indx={3},enable={4}", | 82 | PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},indx={3},eqPoint={4}", |
83 | m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pEqPoint); | 83 | m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pEqPoint); |
84 | PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, pIndex, pEqPoint); | 84 | PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, pIndex, pEqPoint); |
85 | return true; | 85 | return true; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index ff5ac0e..b3347bf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | |||
@@ -605,30 +605,32 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
605 | // pParams = [ BSPhysObject root, BSPhysObject child, int op, object opParams, int op, object opParams, ... ] | 605 | // pParams = [ BSPhysObject root, BSPhysObject child, int op, object opParams, int op, object opParams, ... ] |
606 | case ExtendedPhysics.PhysFunctChangeLinkParams: | 606 | case ExtendedPhysics.PhysFunctChangeLinkParams: |
607 | // There should be two parameters: the childActor and a list of parameters to set | 607 | // There should be two parameters: the childActor and a list of parameters to set |
608 | try | 608 | if (pParams.Length > 2) |
609 | { | 609 | { |
610 | if (pParams.Length > 2) | 610 | BSPrimLinkable child = pParams[1] as BSPrimLinkable; |
611 | BSLinkInfo baseLinkInfo = null; | ||
612 | if (TryGetLinkInfo(child, out baseLinkInfo)) | ||
611 | { | 613 | { |
612 | BSPrimLinkable child = pParams[1] as BSPrimLinkable; | 614 | BSLinkInfoConstraint linkInfo = baseLinkInfo as BSLinkInfoConstraint; |
613 | BSLinkInfo baseLinkInfo = null; | 615 | if (linkInfo != null) |
614 | if (TryGetLinkInfo(child, out baseLinkInfo)) | ||
615 | { | 616 | { |
616 | BSLinkInfoConstraint linkInfo = baseLinkInfo as BSLinkInfoConstraint; | 617 | int valueInt; |
617 | if (linkInfo != null) | 618 | float valueFloat; |
619 | bool valueBool; | ||
620 | OMV.Vector3 valueVector; | ||
621 | OMV.Quaternion valueQuaternion; | ||
622 | int axisLow, axisHigh; | ||
623 | |||
624 | int opIndex = 2; | ||
625 | while (opIndex < pParams.Length) | ||
618 | { | 626 | { |
619 | int valueInt; | 627 | int thisOp = 0; |
620 | float valueFloat; | 628 | string errMsg = ""; |
621 | bool valueBool; | 629 | try |
622 | OMV.Vector3 valueVector; | ||
623 | OMV.Quaternion valueQuaternion; | ||
624 | int axisLow, axisHigh; | ||
625 | |||
626 | int opIndex = 2; | ||
627 | while (opIndex < pParams.Length) | ||
628 | { | 630 | { |
629 | int thisOp = (int)pParams[opIndex]; | 631 | thisOp = (int)pParams[opIndex]; |
630 | DetailLog("{0},BSLinksetConstraint.ChangeLinkParams2,op={1},val={2}", | 632 | DetailLog("{0},BSLinksetConstraint.ChangeLinkParams2,op={1},val={2}", |
631 | linkInfo.member.LocalID, thisOp, pParams[opIndex+1]); | 633 | linkInfo.member.LocalID, thisOp, pParams[opIndex + 1]); |
632 | switch (thisOp) | 634 | switch (thisOp) |
633 | { | 635 | { |
634 | case ExtendedPhysics.PHYS_PARAM_LINK_TYPE: | 636 | case ExtendedPhysics.PHYS_PARAM_LINK_TYPE: |
@@ -646,89 +648,106 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
646 | opIndex += 2; | 648 | opIndex += 2; |
647 | break; | 649 | break; |
648 | case ExtendedPhysics.PHYS_PARAM_FRAMEINA_LOC: | 650 | case ExtendedPhysics.PHYS_PARAM_FRAMEINA_LOC: |
651 | errMsg = "PHYS_PARAM_FRAMEINA_LOC takes one parameter of type vector"; | ||
649 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; | 652 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; |
650 | linkInfo.frameInAloc = valueVector; | 653 | linkInfo.frameInAloc = valueVector; |
651 | opIndex += 2; | 654 | opIndex += 2; |
652 | break; | 655 | break; |
653 | case ExtendedPhysics.PHYS_PARAM_FRAMEINA_ROT: | 656 | case ExtendedPhysics.PHYS_PARAM_FRAMEINA_ROT: |
657 | errMsg = "PHYS_PARAM_FRAMEINA_ROT takes one parameter of type rotation"; | ||
654 | valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1]; | 658 | valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1]; |
655 | linkInfo.frameInArot = valueQuaternion; | 659 | linkInfo.frameInArot = valueQuaternion; |
656 | opIndex += 2; | 660 | opIndex += 2; |
657 | break; | 661 | break; |
658 | case ExtendedPhysics.PHYS_PARAM_FRAMEINB_LOC: | 662 | case ExtendedPhysics.PHYS_PARAM_FRAMEINB_LOC: |
663 | errMsg = "PHYS_PARAM_FRAMEINB_LOC takes one parameter of type vector"; | ||
659 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; | 664 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; |
660 | linkInfo.frameInBloc = valueVector; | 665 | linkInfo.frameInBloc = valueVector; |
661 | opIndex += 2; | 666 | opIndex += 2; |
662 | break; | 667 | break; |
663 | case ExtendedPhysics.PHYS_PARAM_FRAMEINB_ROT: | 668 | case ExtendedPhysics.PHYS_PARAM_FRAMEINB_ROT: |
669 | errMsg = "PHYS_PARAM_FRAMEINB_ROT takes one parameter of type rotation"; | ||
664 | valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1]; | 670 | valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1]; |
665 | linkInfo.frameInBrot = valueQuaternion; | 671 | linkInfo.frameInBrot = valueQuaternion; |
666 | opIndex += 2; | 672 | opIndex += 2; |
667 | break; | 673 | break; |
668 | case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_LOW: | 674 | case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_LOW: |
675 | errMsg = "PHYS_PARAM_LINEAR_LIMIT_LOW takes one parameter of type vector"; | ||
669 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; | 676 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; |
670 | linkInfo.linearLimitLow = valueVector; | 677 | linkInfo.linearLimitLow = valueVector; |
671 | opIndex += 2; | 678 | opIndex += 2; |
672 | break; | 679 | break; |
673 | case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_HIGH: | 680 | case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_HIGH: |
681 | errMsg = "PHYS_PARAM_LINEAR_LIMIT_HIGH takes one parameter of type vector"; | ||
674 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; | 682 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; |
675 | linkInfo.linearLimitHigh = valueVector; | 683 | linkInfo.linearLimitHigh = valueVector; |
676 | opIndex += 2; | 684 | opIndex += 2; |
677 | break; | 685 | break; |
678 | case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_LOW: | 686 | case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_LOW: |
687 | errMsg = "PHYS_PARAM_ANGULAR_LIMIT_LOW takes one parameter of type vector"; | ||
679 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; | 688 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; |
680 | linkInfo.angularLimitLow = valueVector; | 689 | linkInfo.angularLimitLow = valueVector; |
681 | opIndex += 2; | 690 | opIndex += 2; |
682 | break; | 691 | break; |
683 | case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_HIGH: | 692 | case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_HIGH: |
693 | errMsg = "PHYS_PARAM_ANGULAR_LIMIT_HIGH takes one parameter of type vector"; | ||
684 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; | 694 | valueVector = (OMV.Vector3)pParams[opIndex + 1]; |
685 | linkInfo.angularLimitHigh = valueVector; | 695 | linkInfo.angularLimitHigh = valueVector; |
686 | opIndex += 2; | 696 | opIndex += 2; |
687 | break; | 697 | break; |
688 | case ExtendedPhysics.PHYS_PARAM_USE_FRAME_OFFSET: | 698 | case ExtendedPhysics.PHYS_PARAM_USE_FRAME_OFFSET: |
689 | valueBool = (bool)pParams[opIndex + 1]; | 699 | errMsg = "PHYS_PARAM_USE_FRAME_OFFSET takes one parameter of type integer (bool)"; |
700 | valueBool = ((int)pParams[opIndex + 1]) != 0; | ||
690 | linkInfo.useFrameOffset = valueBool; | 701 | linkInfo.useFrameOffset = valueBool; |
691 | opIndex += 2; | 702 | opIndex += 2; |
692 | break; | 703 | break; |
693 | case ExtendedPhysics.PHYS_PARAM_ENABLE_TRANSMOTOR: | 704 | case ExtendedPhysics.PHYS_PARAM_ENABLE_TRANSMOTOR: |
694 | valueBool = (bool)pParams[opIndex + 1]; | 705 | errMsg = "PHYS_PARAM_ENABLE_TRANSMOTOR takes one parameter of type integer (bool)"; |
706 | valueBool = ((int)pParams[opIndex + 1]) != 0; | ||
695 | linkInfo.enableTransMotor = valueBool; | 707 | linkInfo.enableTransMotor = valueBool; |
696 | opIndex += 2; | 708 | opIndex += 2; |
697 | break; | 709 | break; |
698 | case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXVEL: | 710 | case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXVEL: |
711 | errMsg = "PHYS_PARAM_TRANSMOTOR_MAXVEL takes one parameter of type float"; | ||
699 | valueFloat = (float)pParams[opIndex + 1]; | 712 | valueFloat = (float)pParams[opIndex + 1]; |
700 | linkInfo.transMotorMaxVel = valueFloat; | 713 | linkInfo.transMotorMaxVel = valueFloat; |
701 | opIndex += 2; | 714 | opIndex += 2; |
702 | break; | 715 | break; |
703 | case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXFORCE: | 716 | case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXFORCE: |
717 | errMsg = "PHYS_PARAM_TRANSMOTOR_MAXFORCE takes one parameter of type float"; | ||
704 | valueFloat = (float)pParams[opIndex + 1]; | 718 | valueFloat = (float)pParams[opIndex + 1]; |
705 | linkInfo.transMotorMaxForce = valueFloat; | 719 | linkInfo.transMotorMaxForce = valueFloat; |
706 | opIndex += 2; | 720 | opIndex += 2; |
707 | break; | 721 | break; |
708 | case ExtendedPhysics.PHYS_PARAM_CFM: | 722 | case ExtendedPhysics.PHYS_PARAM_CFM: |
723 | errMsg = "PHYS_PARAM_CFM takes one parameter of type float"; | ||
709 | valueFloat = (float)pParams[opIndex + 1]; | 724 | valueFloat = (float)pParams[opIndex + 1]; |
710 | linkInfo.cfm = valueFloat; | 725 | linkInfo.cfm = valueFloat; |
711 | opIndex += 2; | 726 | opIndex += 2; |
712 | break; | 727 | break; |
713 | case ExtendedPhysics.PHYS_PARAM_ERP: | 728 | case ExtendedPhysics.PHYS_PARAM_ERP: |
729 | errMsg = "PHYS_PARAM_ERP takes one parameter of type float"; | ||
714 | valueFloat = (float)pParams[opIndex + 1]; | 730 | valueFloat = (float)pParams[opIndex + 1]; |
715 | linkInfo.erp = valueFloat; | 731 | linkInfo.erp = valueFloat; |
716 | opIndex += 2; | 732 | opIndex += 2; |
717 | break; | 733 | break; |
718 | case ExtendedPhysics.PHYS_PARAM_SOLVER_ITERATIONS: | 734 | case ExtendedPhysics.PHYS_PARAM_SOLVER_ITERATIONS: |
735 | errMsg = "PHYS_PARAM_SOLVER_ITERATIONS takes one parameter of type float"; | ||
719 | valueFloat = (float)pParams[opIndex + 1]; | 736 | valueFloat = (float)pParams[opIndex + 1]; |
720 | linkInfo.solverIterations = valueFloat; | 737 | linkInfo.solverIterations = valueFloat; |
721 | opIndex += 2; | 738 | opIndex += 2; |
722 | break; | 739 | break; |
723 | case ExtendedPhysics.PHYS_PARAM_SPRING_AXIS_ENABLE: | 740 | case ExtendedPhysics.PHYS_PARAM_SPRING_AXIS_ENABLE: |
741 | errMsg = "PHYS_PARAM_SPRING_AXIS_ENABLE takes two parameters of types integer and integer (bool)"; | ||
724 | valueInt = (int)pParams[opIndex + 1]; | 742 | valueInt = (int)pParams[opIndex + 1]; |
725 | valueBool = ((int)pParams[opIndex + 2] != 0); | 743 | valueBool = ((int)pParams[opIndex + 2]) != 0; |
726 | GetAxisRange(valueInt, out axisLow, out axisHigh); | 744 | GetAxisRange(valueInt, out axisLow, out axisHigh); |
727 | for (int ii = axisLow; ii <= axisHigh; ii++) | 745 | for (int ii = axisLow; ii <= axisHigh; ii++) |
728 | linkInfo.springAxisEnable[ii] = valueBool; | 746 | linkInfo.springAxisEnable[ii] = valueBool; |
729 | opIndex += 3; | 747 | opIndex += 3; |
730 | break; | 748 | break; |
731 | case ExtendedPhysics.PHYS_PARAM_SPRING_DAMPING: | 749 | case ExtendedPhysics.PHYS_PARAM_SPRING_DAMPING: |
750 | errMsg = "PHYS_PARAM_SPRING_DAMPING takes two parameters of types integer and float"; | ||
732 | valueInt = (int)pParams[opIndex + 1]; | 751 | valueInt = (int)pParams[opIndex + 1]; |
733 | valueFloat = (float)pParams[opIndex + 2]; | 752 | valueFloat = (float)pParams[opIndex + 2]; |
734 | GetAxisRange(valueInt, out axisLow, out axisHigh); | 753 | GetAxisRange(valueInt, out axisLow, out axisHigh); |
@@ -737,6 +756,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
737 | opIndex += 3; | 756 | opIndex += 3; |
738 | break; | 757 | break; |
739 | case ExtendedPhysics.PHYS_PARAM_SPRING_STIFFNESS: | 758 | case ExtendedPhysics.PHYS_PARAM_SPRING_STIFFNESS: |
759 | errMsg = "PHYS_PARAM_SPRING_STIFFNESS takes two parameters of types integer and float"; | ||
740 | valueInt = (int)pParams[opIndex + 1]; | 760 | valueInt = (int)pParams[opIndex + 1]; |
741 | valueFloat = (float)pParams[opIndex + 2]; | 761 | valueFloat = (float)pParams[opIndex + 2]; |
742 | GetAxisRange(valueInt, out axisLow, out axisHigh); | 762 | GetAxisRange(valueInt, out axisLow, out axisHigh); |
@@ -745,7 +765,8 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
745 | opIndex += 3; | 765 | opIndex += 3; |
746 | break; | 766 | break; |
747 | case ExtendedPhysics.PHYS_PARAM_USE_LINEAR_FRAMEA: | 767 | case ExtendedPhysics.PHYS_PARAM_USE_LINEAR_FRAMEA: |
748 | valueBool = (bool)pParams[opIndex + 1]; | 768 | errMsg = "PHYS_PARAM_USE_LINEAR_FRAMEA takes one parameter of type integer (bool)"; |
769 | valueBool = ((int)pParams[opIndex + 1]) != 0; | ||
749 | linkInfo.useLinearReferenceFrameA = valueBool; | 770 | linkInfo.useLinearReferenceFrameA = valueBool; |
750 | opIndex += 2; | 771 | opIndex += 2; |
751 | break; | 772 | break; |
@@ -753,18 +774,22 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
753 | break; | 774 | break; |
754 | } | 775 | } |
755 | } | 776 | } |
777 | catch (InvalidCastException e) | ||
778 | { | ||
779 | m_physicsScene.Logger.WarnFormat("{0} value of wrong type in physSetLinksetParams: {1}, err={2}", | ||
780 | LogHeader, errMsg, e); | ||
781 | } | ||
782 | catch (Exception e) | ||
783 | { | ||
784 | m_physicsScene.Logger.WarnFormat("{0} bad parameters in physSetLinksetParams: {1}", LogHeader, e); | ||
785 | } | ||
756 | } | 786 | } |
757 | // Something changed so a rebuild is in order | ||
758 | Refresh(child); | ||
759 | } | 787 | } |
788 | // Something changed so a rebuild is in order | ||
789 | Refresh(child); | ||
760 | } | 790 | } |
761 | } | 791 | } |
762 | catch (Exception e) | 792 | break; |
763 | { | ||
764 | // There are many ways to mess up the parameters. If not just right don't fail without some error. | ||
765 | m_physicsScene.Logger.WarnFormat("{0} bad parameters in physSetLinksetParams: {1}", LogHeader, e); | ||
766 | } | ||
767 | break; | ||
768 | default: | 793 | default: |
769 | ret = base.Extension(pFunct, pParams); | 794 | ret = base.Extension(pFunct, pParams); |
770 | break; | 795 | break; |
@@ -779,11 +804,11 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
779 | { | 804 | { |
780 | switch (rangeSpec) | 805 | switch (rangeSpec) |
781 | { | 806 | { |
782 | case ExtendedPhysics.PHYS_AXIS_ALL_LINEAR: | 807 | case ExtendedPhysics.PHYS_AXIS_LINEAR_ALL: |
783 | low = 0; | 808 | low = 0; |
784 | high = 2; | 809 | high = 2; |
785 | break; | 810 | break; |
786 | case ExtendedPhysics.PHYS_AXIS_ALL_ANGULAR: | 811 | case ExtendedPhysics.PHYS_AXIS_ANGULAR_ALL: |
787 | low = 3; | 812 | low = 3; |
788 | high = 5; | 813 | high = 5; |
789 | break; | 814 | break; |