diff options
author | Dahlia Trimble | 2009-06-03 05:31:53 +0000 |
---|---|---|
committer | Dahlia Trimble | 2009-06-03 05:31:53 +0000 |
commit | b64c484d269d2dfef7aaed21b044eec14d1dd74e (patch) | |
tree | 3559f810c281bbdabdc721e309125efa699cac88 | |
parent | revert r9765 due to too many errors on some compilers. Affects Mantis #3759 (diff) | |
download | opensim-SC_OLD-b64c484d269d2dfef7aaed21b044eec14d1dd74e.zip opensim-SC_OLD-b64c484d269d2dfef7aaed21b044eec14d1dd74e.tar.gz opensim-SC_OLD-b64c484d269d2dfef7aaed21b044eec14d1dd74e.tar.bz2 opensim-SC_OLD-b64c484d269d2dfef7aaed21b044eec14d1dd74e.tar.xz |
Thanks aduffy70 for Mantis #3762: A patch to fix llGround, llGroundNormal, and llGroundSlope
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 122 |
1 files changed, 80 insertions, 42 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d6cd9d3..a10ca3d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -1016,21 +1016,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1016 | public LSL_Float llGround(LSL_Vector offset) | 1016 | public LSL_Float llGround(LSL_Vector offset) |
1017 | { | 1017 | { |
1018 | m_host.AddScriptLPS(1); | 1018 | m_host.AddScriptLPS(1); |
1019 | Vector3 pos = m_host.GetWorldPosition(); | 1019 | Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, |
1020 | int x = (int)(pos.X + offset.x); | 1020 | (float)offset.y, |
1021 | int y = (int)(pos.Y + offset.y); | 1021 | (float)offset.z); |
1022 | |||
1023 | //Get the slope normal. This gives us the equation of the plane tangent to the slope. | ||
1024 | LSL_Vector vsn = llGroundNormal(offset); | ||
1022 | 1025 | ||
1023 | // Clamp to valid position | 1026 | // Clamp to valid position |
1024 | if (x < 0) | 1027 | if (pos.X < 0) |
1025 | x = 0; | 1028 | pos.X = 0; |
1026 | else if (x >= World.Heightmap.Width) | 1029 | else if (pos.X >= World.Heightmap.Width) |
1027 | x = World.Heightmap.Width - 1; | 1030 | pos.X = World.Heightmap.Width - 1; |
1028 | if (y < 0) | 1031 | if (pos.Y < 0) |
1029 | y = 0; | 1032 | pos.Y = 0; |
1030 | else if (y >= World.Heightmap.Height) | 1033 | else if (pos.Y >= World.Heightmap.Height) |
1031 | y = World.Heightmap.Height - 1; | 1034 | pos.Y = World.Heightmap.Height - 1; |
1032 | 1035 | ||
1033 | return World.Heightmap[x, y]; | 1036 | //Get the height for the integer coordinates from the Heightmap |
1037 | float baseheight = (float)World.Heightmap[(int)pos.X, (int)pos.Y]; | ||
1038 | |||
1039 | //Calculate the difference between the actual coordinates and the integer coordinates | ||
1040 | float xdiff = pos.X - (float)((int)pos.X); | ||
1041 | float ydiff = pos.Y - (float)((int)pos.Y); | ||
1042 | |||
1043 | //Use the equation of the tangent plane to adjust the height to account for slope | ||
1044 | |||
1045 | return (((vsn.x * xdiff) + (vsn.y * ydiff)) / (-1 * vsn.z)) + baseheight; | ||
1034 | } | 1046 | } |
1035 | 1047 | ||
1036 | public LSL_Float llCloud(LSL_Vector offset) | 1048 | public LSL_Float llCloud(LSL_Vector offset) |
@@ -5562,45 +5574,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5562 | public LSL_Vector llGroundSlope(LSL_Vector offset) | 5574 | public LSL_Vector llGroundSlope(LSL_Vector offset) |
5563 | { | 5575 | { |
5564 | m_host.AddScriptLPS(1); | 5576 | m_host.AddScriptLPS(1); |
5577 | //Get the slope normal. This gives us the equation of the plane tangent to the slope. | ||
5578 | LSL_Vector vsn = llGroundNormal(offset); | ||
5565 | 5579 | ||
5566 | Vector3 pos = m_host.AbsolutePosition + new Vector3((float)offset.x, | 5580 | //Plug the x,y coordinates of the slope normal into the equation of the plane to get |
5581 | //the height of that point on the plane. The resulting vector gives the slope. | ||
5582 | Vector3 vsl = new Vector3(); | ||
5583 | vsl.X = (float)vsn.x; | ||
5584 | vsl.Y = (float)vsn.y; | ||
5585 | vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); | ||
5586 | vsl.Normalize(); | ||
5587 | //Normalization might be overkill here | ||
5588 | |||
5589 | return new LSL_Vector(vsl.X, vsl.Y, vsl.Z); | ||
5590 | } | ||
5591 | |||
5592 | public LSL_Vector llGroundNormal(LSL_Vector offset) | ||
5593 | { | ||
5594 | m_host.AddScriptLPS(1); | ||
5595 | Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, | ||
5567 | (float)offset.y, | 5596 | (float)offset.y, |
5568 | (float)offset.z); | 5597 | (float)offset.z); |
5569 | 5598 | // Clamp to valid position | |
5599 | if (pos.X < 0) | ||
5600 | pos.X = 0; | ||
5601 | else if (pos.X >= World.Heightmap.Width) | ||
5602 | pos.X = World.Heightmap.Width - 1; | ||
5603 | if (pos.Y < 0) | ||
5604 | pos.Y = 0; | ||
5605 | else if (pos.Y >= World.Heightmap.Height) | ||
5606 | pos.Y = World.Heightmap.Height - 1; | ||
5607 | |||
5608 | //Find two points in addition to the position to define a plane | ||
5570 | Vector3 p0 = new Vector3(pos.X, pos.Y, | 5609 | Vector3 p0 = new Vector3(pos.X, pos.Y, |
5571 | (float)llGround( | 5610 | (float)World.Heightmap[(int)pos.X, (int)pos.Y]); |
5572 | new LSL_Vector(offset.x, offset.y, offset.z) | 5611 | Vector3 p1 = new Vector3(); |
5573 | )); | 5612 | Vector3 p2 = new Vector3(); |
5574 | Vector3 p1 = new Vector3(pos.X + 1, pos.Y, | 5613 | if ((pos.X + 1.0f) >= World.Heightmap.Width) |
5575 | (float)llGround( | 5614 | p1 = new Vector3(pos.X + 1.0f, pos.Y, |
5576 | new LSL_Vector(offset.x + 1, offset.y, offset.z) | 5615 | (float)World.Heightmap[(int)pos.X, (int)pos.Y]); |
5577 | )); | 5616 | else |
5578 | Vector3 p2 = new Vector3(pos.X, pos.Y + 1, | 5617 | p1 = new Vector3(pos.X + 1.0f, pos.Y, |
5579 | (float)llGround( | 5618 | (float)World.Heightmap[(int)(pos.X + 1.0f), (int)pos.Y]); |
5580 | new LSL_Vector(offset.x, offset.y + 1, offset.z) | 5619 | if ((pos.Y + 1.0f) >= World.Heightmap.Height) |
5581 | )); | 5620 | p2 = new Vector3(pos.X, pos.Y + 1.0f, |
5621 | (float)World.Heightmap[(int)pos.X, (int)pos.Y]); | ||
5622 | else | ||
5623 | p2 = new Vector3(pos.X, pos.Y + 1.0f, | ||
5624 | (float)World.Heightmap[(int)pos.X, (int)(pos.Y + 1.0f)]); | ||
5582 | 5625 | ||
5626 | //Find normalized vectors from p0 to p1 and p0 to p2 | ||
5583 | Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); | 5627 | Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); |
5584 | Vector3 v1 = new Vector3(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); | 5628 | Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z); |
5585 | |||
5586 | v0.Normalize(); | 5629 | v0.Normalize(); |
5587 | v1.Normalize(); | 5630 | v1.Normalize(); |
5588 | 5631 | ||
5589 | Vector3 tv = new Vector3(); | 5632 | //Find the cross product of the vectors (the slope normal). |
5590 | tv.X = (v0.Y * v1.Z) - (v0.Z * v1.Y); | 5633 | Vector3 vsn = new Vector3(); |
5591 | tv.Y = (v0.Z * v1.X) - (v0.X * v1.Z); | 5634 | vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y); |
5592 | tv.Z = (v0.X * v1.Y) - (v0.Y * v1.X); | 5635 | vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z); |
5593 | if ((tv.X == 0) && (tv.Y == 0)) | 5636 | vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X); |
5594 | tv.Z = 0; | 5637 | vsn.Normalize(); |
5638 | //I believe the crossproduct of two normalized vectors is a normalized vector so | ||
5639 | //this normalization may be overkill | ||
5595 | 5640 | ||
5596 | return new LSL_Vector(tv.X, tv.Y, tv.Z); | 5641 | return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); |
5597 | } | ||
5598 | |||
5599 | public LSL_Vector llGroundNormal(LSL_Vector offset) | ||
5600 | { | ||
5601 | m_host.AddScriptLPS(1); | ||
5602 | LSL_Vector x = llGroundSlope(offset); | ||
5603 | return new LSL_Vector(x.x, x.y, 1.0); | ||
5604 | } | 5642 | } |
5605 | 5643 | ||
5606 | public LSL_Vector llGroundContour(LSL_Vector offset) | 5644 | public LSL_Vector llGroundContour(LSL_Vector offset) |