diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 88e884d..cf8517d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -6570,6 +6570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6570 | 6570 | ||
6571 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) | 6571 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) |
6572 | { | 6572 | { |
6573 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
6573 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | 6574 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); |
6574 | 6575 | ||
6575 | if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && | 6576 | if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && |
@@ -6651,8 +6652,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6651 | { | 6652 | { |
6652 | twist.y = 1.0f; | 6653 | twist.y = 1.0f; |
6653 | } | 6654 | } |
6654 | shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x); | 6655 | // A fairly large precision error occurs for some calculations, |
6655 | shapeBlock.PathTwist = (sbyte)(100 * twist.y); | 6656 | // if a float or double is directly cast to a byte or sbyte |
6657 | // variable, in both .Net and Mono. In .Net, coding | ||
6658 | // "(sbyte)(float)(some expression)" corrects the precision | ||
6659 | // errors. But this does not work for Mono. This longer coding | ||
6660 | // form of creating a tempoary float variable from the | ||
6661 | // expression first, then casting that variable to a byte or | ||
6662 | // sbyte, works for both .Net and Mono. These types of | ||
6663 | // assignments occur in SetPrimtiveBlockShapeParams and | ||
6664 | // SetPrimitiveShapeParams in support of llSetPrimitiveParams. | ||
6665 | tempFloat = (float)(100.0d * twist.x); | ||
6666 | shapeBlock.PathTwistBegin = (sbyte)tempFloat; | ||
6667 | tempFloat = (float)(100.0d * twist.y); | ||
6668 | shapeBlock.PathTwist = (sbyte)tempFloat; | ||
6656 | 6669 | ||
6657 | shapeBlock.ObjectLocalID = part.LocalId; | 6670 | shapeBlock.ObjectLocalID = part.LocalId; |
6658 | 6671 | ||
@@ -6663,6 +6676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6663 | // Prim type box, cylinder and prism. | 6676 | // Prim type box, cylinder and prism. |
6664 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) | 6677 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) |
6665 | { | 6678 | { |
6679 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
6666 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 6680 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
6667 | 6681 | ||
6668 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 6682 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -6683,8 +6697,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6683 | { | 6697 | { |
6684 | taper_b.y = 2f; | 6698 | taper_b.y = 2f; |
6685 | } | 6699 | } |
6686 | shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x)); | 6700 | tempFloat = (float)(100.0d * (2.0d - taper_b.x)); |
6687 | shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y)); | 6701 | shapeBlock.PathScaleX = (byte)tempFloat; |
6702 | tempFloat = (float)(100.0d * (2.0d - taper_b.y)); | ||
6703 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
6688 | if (topshear.x < -0.5f) | 6704 | if (topshear.x < -0.5f) |
6689 | { | 6705 | { |
6690 | topshear.x = -0.5f; | 6706 | topshear.x = -0.5f; |
@@ -6701,8 +6717,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6701 | { | 6717 | { |
6702 | topshear.y = 0.5f; | 6718 | topshear.y = 0.5f; |
6703 | } | 6719 | } |
6704 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 6720 | tempFloat = (float)(100.0d * topshear.x); |
6705 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 6721 | shapeBlock.PathShearX = (byte)tempFloat; |
6722 | tempFloat = (float)(100.0d * topshear.y); | ||
6723 | shapeBlock.PathShearY = (byte)tempFloat; | ||
6706 | 6724 | ||
6707 | part.Shape.SculptEntry = false; | 6725 | part.Shape.SculptEntry = false; |
6708 | part.UpdateShape(shapeBlock); | 6726 | part.UpdateShape(shapeBlock); |
@@ -6752,6 +6770,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6752 | // Prim type torus, tube and ring. | 6770 | // Prim type torus, tube and ring. |
6753 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) | 6771 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) |
6754 | { | 6772 | { |
6773 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
6755 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 6774 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
6756 | 6775 | ||
6757 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 6776 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -6776,8 +6795,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6776 | { | 6795 | { |
6777 | holesize.y = 0.5f; | 6796 | holesize.y = 0.5f; |
6778 | } | 6797 | } |
6779 | shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x)); | 6798 | tempFloat = (float)(100.0d * (2.0d - holesize.x)); |
6780 | shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y)); | 6799 | shapeBlock.PathScaleX = (byte)tempFloat; |
6800 | tempFloat = (float)(100.0d * (2.0d - holesize.y)); | ||
6801 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
6781 | if (topshear.x < -0.5f) | 6802 | if (topshear.x < -0.5f) |
6782 | { | 6803 | { |
6783 | topshear.x = -0.5f; | 6804 | topshear.x = -0.5f; |
@@ -6794,8 +6815,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6794 | { | 6815 | { |
6795 | topshear.y = 0.5f; | 6816 | topshear.y = 0.5f; |
6796 | } | 6817 | } |
6797 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 6818 | tempFloat = (float)(100.0d * topshear.x); |
6798 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 6819 | shapeBlock.PathShearX = (byte)tempFloat; |
6820 | tempFloat = (float)(100.0d * topshear.y); | ||
6821 | shapeBlock.PathShearY = (byte)tempFloat; | ||
6799 | if (profilecut.x < 0f) | 6822 | if (profilecut.x < 0f) |
6800 | { | 6823 | { |
6801 | profilecut.x = 0f; | 6824 | profilecut.x = 0f; |
@@ -6839,8 +6862,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6839 | { | 6862 | { |
6840 | taper_a.y = 1f; | 6863 | taper_a.y = 1f; |
6841 | } | 6864 | } |
6842 | shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x); | 6865 | tempFloat = (float)(100.0d * taper_a.x); |
6843 | shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y); | 6866 | shapeBlock.PathTaperX = (sbyte)tempFloat; |
6867 | tempFloat = (float)(100.0d * taper_a.y); | ||
6868 | shapeBlock.PathTaperY = (sbyte)tempFloat; | ||
6844 | if (revolutions < 1f) | 6869 | if (revolutions < 1f) |
6845 | { | 6870 | { |
6846 | revolutions = 1f; | 6871 | revolutions = 1f; |
@@ -6849,7 +6874,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6849 | { | 6874 | { |
6850 | revolutions = 4f; | 6875 | revolutions = 4f; |
6851 | } | 6876 | } |
6852 | shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0)); | 6877 | tempFloat = 66.66667f * (revolutions - 1.0f); |
6878 | shapeBlock.PathRevolutions = (byte)tempFloat; | ||
6853 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 | 6879 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 |
6854 | if (radiusoffset < 0f) | 6880 | if (radiusoffset < 0f) |
6855 | { | 6881 | { |
@@ -6859,7 +6885,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6859 | { | 6885 | { |
6860 | radiusoffset = 1f; | 6886 | radiusoffset = 1f; |
6861 | } | 6887 | } |
6862 | shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset); | 6888 | tempFloat = 100.0f * radiusoffset; |
6889 | shapeBlock.PathRadiusOffset = (sbyte)tempFloat; | ||
6863 | if (skew < -0.95f) | 6890 | if (skew < -0.95f) |
6864 | { | 6891 | { |
6865 | skew = -0.95f; | 6892 | skew = -0.95f; |
@@ -6868,7 +6895,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6868 | { | 6895 | { |
6869 | skew = 0.95f; | 6896 | skew = 0.95f; |
6870 | } | 6897 | } |
6871 | shapeBlock.PathSkew = (sbyte)(100 * skew); | 6898 | tempFloat = 100.0f * skew; |
6899 | shapeBlock.PathSkew = (sbyte)tempFloat; | ||
6872 | 6900 | ||
6873 | part.Shape.SculptEntry = false; | 6901 | part.Shape.SculptEntry = false; |
6874 | part.UpdateShape(shapeBlock); | 6902 | part.UpdateShape(shapeBlock); |
@@ -7681,10 +7709,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7681 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); | 7709 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); |
7682 | 7710 | ||
7683 | // float revolutions | 7711 | // float revolutions |
7684 | res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned | 7712 | res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); |
7685 | // byte is being used to represent the entire | 7713 | // Slightly inaccurate, because an unsigned byte is being used to represent |
7686 | // range of floating-point values from 1.0 | 7714 | // the entire range of floating-point values from 1.0 through 4.0 (which is how |
7687 | // through 4.0 (which is how SL does it). | 7715 | // SL does it). |
7716 | // | ||
7717 | // Using these formulas to store and retrieve PathRevolutions, it is not | ||
7718 | // possible to use all values between 1.00 and 4.00. For instance, you can't | ||
7719 | // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you | ||
7720 | // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them | ||
7721 | // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar | ||
7722 | // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. | ||
7723 | // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value | ||
7724 | // such as 1.10. So, SL must store and retreive the actual user input rather | ||
7725 | // than only storing the encoded value. | ||
7688 | 7726 | ||
7689 | // float radiusoffset | 7727 | // float radiusoffset |
7690 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); | 7728 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); |