diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs')
-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 6f34168..18c0dd2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -7040,6 +7040,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7040 | 7040 | ||
7041 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) | 7041 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) |
7042 | { | 7042 | { |
7043 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
7043 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | 7044 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); |
7044 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 7045 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
7045 | return shapeBlock; | 7046 | return shapeBlock; |
@@ -7123,8 +7124,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7123 | { | 7124 | { |
7124 | twist.y = 1.0f; | 7125 | twist.y = 1.0f; |
7125 | } | 7126 | } |
7126 | shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x); | 7127 | // A fairly large precision error occurs for some calculations, |
7127 | shapeBlock.PathTwist = (sbyte)(100 * twist.y); | 7128 | // if a float or double is directly cast to a byte or sbyte |
7129 | // variable, in both .Net and Mono. In .Net, coding | ||
7130 | // "(sbyte)(float)(some expression)" corrects the precision | ||
7131 | // errors. But this does not work for Mono. This longer coding | ||
7132 | // form of creating a tempoary float variable from the | ||
7133 | // expression first, then casting that variable to a byte or | ||
7134 | // sbyte, works for both .Net and Mono. These types of | ||
7135 | // assignments occur in SetPrimtiveBlockShapeParams and | ||
7136 | // SetPrimitiveShapeParams in support of llSetPrimitiveParams. | ||
7137 | tempFloat = (float)(100.0d * twist.x); | ||
7138 | shapeBlock.PathTwistBegin = (sbyte)tempFloat; | ||
7139 | tempFloat = (float)(100.0d * twist.y); | ||
7140 | shapeBlock.PathTwist = (sbyte)tempFloat; | ||
7128 | 7141 | ||
7129 | shapeBlock.ObjectLocalID = part.LocalId; | 7142 | shapeBlock.ObjectLocalID = part.LocalId; |
7130 | 7143 | ||
@@ -7138,6 +7151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7138 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 7151 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
7139 | return; | 7152 | return; |
7140 | 7153 | ||
7154 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
7141 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7155 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7142 | 7156 | ||
7143 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 7157 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -7158,8 +7172,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7158 | { | 7172 | { |
7159 | taper_b.y = 2f; | 7173 | taper_b.y = 2f; |
7160 | } | 7174 | } |
7161 | shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x)); | 7175 | tempFloat = (float)(100.0d * (2.0d - taper_b.x)); |
7162 | shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y)); | 7176 | shapeBlock.PathScaleX = (byte)tempFloat; |
7177 | tempFloat = (float)(100.0d * (2.0d - taper_b.y)); | ||
7178 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
7163 | if (topshear.x < -0.5f) | 7179 | if (topshear.x < -0.5f) |
7164 | { | 7180 | { |
7165 | topshear.x = -0.5f; | 7181 | topshear.x = -0.5f; |
@@ -7176,8 +7192,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7176 | { | 7192 | { |
7177 | topshear.y = 0.5f; | 7193 | topshear.y = 0.5f; |
7178 | } | 7194 | } |
7179 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 7195 | tempFloat = (float)(100.0d * topshear.x); |
7180 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 7196 | shapeBlock.PathShearX = (byte)tempFloat; |
7197 | tempFloat = (float)(100.0d * topshear.y); | ||
7198 | shapeBlock.PathShearY = (byte)tempFloat; | ||
7181 | 7199 | ||
7182 | part.Shape.SculptEntry = false; | 7200 | part.Shape.SculptEntry = false; |
7183 | part.UpdateShape(shapeBlock); | 7201 | part.UpdateShape(shapeBlock); |
@@ -7233,6 +7251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7233 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 7251 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
7234 | return; | 7252 | return; |
7235 | 7253 | ||
7254 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
7236 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7255 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7237 | 7256 | ||
7238 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 7257 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -7257,8 +7276,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7257 | { | 7276 | { |
7258 | holesize.y = 0.5f; | 7277 | holesize.y = 0.5f; |
7259 | } | 7278 | } |
7260 | shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x)); | 7279 | tempFloat = (float)(100.0d * (2.0d - holesize.x)); |
7261 | shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y)); | 7280 | shapeBlock.PathScaleX = (byte)tempFloat; |
7281 | tempFloat = (float)(100.0d * (2.0d - holesize.y)); | ||
7282 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
7262 | if (topshear.x < -0.5f) | 7283 | if (topshear.x < -0.5f) |
7263 | { | 7284 | { |
7264 | topshear.x = -0.5f; | 7285 | topshear.x = -0.5f; |
@@ -7275,8 +7296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7275 | { | 7296 | { |
7276 | topshear.y = 0.5f; | 7297 | topshear.y = 0.5f; |
7277 | } | 7298 | } |
7278 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 7299 | tempFloat = (float)(100.0d * topshear.x); |
7279 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 7300 | shapeBlock.PathShearX = (byte)tempFloat; |
7301 | tempFloat = (float)(100.0d * topshear.y); | ||
7302 | shapeBlock.PathShearY = (byte)tempFloat; | ||
7280 | if (profilecut.x < 0f) | 7303 | if (profilecut.x < 0f) |
7281 | { | 7304 | { |
7282 | profilecut.x = 0f; | 7305 | profilecut.x = 0f; |
@@ -7320,8 +7343,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7320 | { | 7343 | { |
7321 | taper_a.y = 1f; | 7344 | taper_a.y = 1f; |
7322 | } | 7345 | } |
7323 | shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x); | 7346 | tempFloat = (float)(100.0d * taper_a.x); |
7324 | shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y); | 7347 | shapeBlock.PathTaperX = (sbyte)tempFloat; |
7348 | tempFloat = (float)(100.0d * taper_a.y); | ||
7349 | shapeBlock.PathTaperY = (sbyte)tempFloat; | ||
7325 | if (revolutions < 1f) | 7350 | if (revolutions < 1f) |
7326 | { | 7351 | { |
7327 | revolutions = 1f; | 7352 | revolutions = 1f; |
@@ -7330,7 +7355,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7330 | { | 7355 | { |
7331 | revolutions = 4f; | 7356 | revolutions = 4f; |
7332 | } | 7357 | } |
7333 | shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0)); | 7358 | tempFloat = 66.66667f * (revolutions - 1.0f); |
7359 | shapeBlock.PathRevolutions = (byte)tempFloat; | ||
7334 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 | 7360 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 |
7335 | if (radiusoffset < 0f) | 7361 | if (radiusoffset < 0f) |
7336 | { | 7362 | { |
@@ -7340,7 +7366,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7340 | { | 7366 | { |
7341 | radiusoffset = 1f; | 7367 | radiusoffset = 1f; |
7342 | } | 7368 | } |
7343 | shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset); | 7369 | tempFloat = 100.0f * radiusoffset; |
7370 | shapeBlock.PathRadiusOffset = (sbyte)tempFloat; | ||
7344 | if (skew < -0.95f) | 7371 | if (skew < -0.95f) |
7345 | { | 7372 | { |
7346 | skew = -0.95f; | 7373 | skew = -0.95f; |
@@ -7349,7 +7376,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7349 | { | 7376 | { |
7350 | skew = 0.95f; | 7377 | skew = 0.95f; |
7351 | } | 7378 | } |
7352 | shapeBlock.PathSkew = (sbyte)(100 * skew); | 7379 | tempFloat = 100.0f * skew; |
7380 | shapeBlock.PathSkew = (sbyte)tempFloat; | ||
7353 | 7381 | ||
7354 | part.Shape.SculptEntry = false; | 7382 | part.Shape.SculptEntry = false; |
7355 | part.UpdateShape(shapeBlock); | 7383 | part.UpdateShape(shapeBlock); |
@@ -8268,10 +8296,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8268 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); | 8296 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); |
8269 | 8297 | ||
8270 | // float revolutions | 8298 | // float revolutions |
8271 | res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned | 8299 | res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); |
8272 | // byte is being used to represent the entire | 8300 | // Slightly inaccurate, because an unsigned byte is being used to represent |
8273 | // range of floating-point values from 1.0 | 8301 | // the entire range of floating-point values from 1.0 through 4.0 (which is how |
8274 | // through 4.0 (which is how SL does it). | 8302 | // SL does it). |
8303 | // | ||
8304 | // Using these formulas to store and retrieve PathRevolutions, it is not | ||
8305 | // possible to use all values between 1.00 and 4.00. For instance, you can't | ||
8306 | // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you | ||
8307 | // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them | ||
8308 | // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar | ||
8309 | // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. | ||
8310 | // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value | ||
8311 | // such as 1.10. So, SL must store and retreive the actual user input rather | ||
8312 | // than only storing the encoded value. | ||
8275 | 8313 | ||
8276 | // float radiusoffset | 8314 | // float radiusoffset |
8277 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); | 8315 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); |