diff options
Diffstat (limited to 'OpenSim')
3 files changed, 275 insertions, 207 deletions
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 91252f7..df5ac92 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs | |||
@@ -111,6 +111,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
111 | asset = assetService.GetCached(cacheID.ToString()); | 111 | asset = assetService.GetCached(cacheID.ToString()); |
112 | if (asset != null) | 112 | if (asset != null) |
113 | { | 113 | { |
114 | // m_log.DebugFormat( | ||
115 | // "[TERRAIN SPLAT]: Got asset service cached terrain texture {0} {1}", i, asset.ID); | ||
116 | |||
114 | try | 117 | try |
115 | { | 118 | { |
116 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) | 119 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) |
@@ -129,6 +132,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
129 | asset = assetService.Get(textureIDs[i].ToString()); | 132 | asset = assetService.Get(textureIDs[i].ToString()); |
130 | if (asset != null) | 133 | if (asset != null) |
131 | { | 134 | { |
135 | // m_log.DebugFormat( | ||
136 | // "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID); | ||
137 | |||
132 | try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } | 138 | try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } |
133 | catch (Exception ex) | 139 | catch (Exception ex) |
134 | { | 140 | { |
@@ -137,15 +143,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
137 | } | 143 | } |
138 | 144 | ||
139 | if (detailTexture[i] != null) | 145 | if (detailTexture[i] != null) |
140 | { | 146 | { |
141 | Bitmap bitmap = detailTexture[i]; | ||
142 | |||
143 | // Make sure this texture is the correct size, otherwise resize | 147 | // Make sure this texture is the correct size, otherwise resize |
144 | if (bitmap.Width != 256 || bitmap.Height != 256) | 148 | if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) |
145 | { | 149 | { |
146 | using (Bitmap origBitmap = bitmap) | 150 | using (Bitmap origBitmap = detailTexture[i]) |
147 | { | 151 | { |
148 | bitmap = ImageUtils.ResizeImage(origBitmap, 256, 256); | 152 | detailTexture[i] = ImageUtils.ResizeImage(origBitmap, 256, 256); |
149 | } | 153 | } |
150 | } | 154 | } |
151 | 155 | ||
@@ -153,7 +157,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
153 | byte[] data; | 157 | byte[] data; |
154 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) | 158 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) |
155 | { | 159 | { |
156 | bitmap.Save(stream, ImageFormat.Png); | 160 | detailTexture[i].Save(stream, ImageFormat.Png); |
157 | data = stream.ToArray(); | 161 | data = stream.ToArray(); |
158 | } | 162 | } |
159 | 163 | ||
@@ -185,6 +189,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
185 | { | 189 | { |
186 | if (detailTexture[i] == null) | 190 | if (detailTexture[i] == null) |
187 | { | 191 | { |
192 | // m_log.DebugFormat( | ||
193 | // "[TERRAIN SPLAT]: Generating solid colour for missing texture {0}", i); | ||
194 | |||
188 | // Create a solid color texture for this layer | 195 | // Create a solid color texture for this layer |
189 | detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | 196 | detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); |
190 | using (Graphics gfx = Graphics.FromImage(detailTexture[i])) | 197 | using (Graphics gfx = Graphics.FromImage(detailTexture[i])) |
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index 53022ad..4049ee1 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs | |||
@@ -236,6 +236,13 @@ namespace PrimMesher | |||
236 | this.U = u; | 236 | this.U = u; |
237 | this.V = v; | 237 | this.V = v; |
238 | } | 238 | } |
239 | |||
240 | public UVCoord Flip() | ||
241 | { | ||
242 | this.U = 1.0f - this.U; | ||
243 | this.V = 1.0f - this.V; | ||
244 | return this; | ||
245 | } | ||
239 | } | 246 | } |
240 | 247 | ||
241 | public struct Face | 248 | public struct Face |
@@ -603,40 +610,40 @@ namespace PrimMesher | |||
603 | /// <summary> | 610 | /// <summary> |
604 | /// generates a profile for extrusion | 611 | /// generates a profile for extrusion |
605 | /// </summary> | 612 | /// </summary> |
606 | internal class Profile | 613 | public class Profile |
607 | { | 614 | { |
608 | private const float twoPi = 2.0f * (float)Math.PI; | 615 | private const float twoPi = 2.0f * (float)Math.PI; |
609 | 616 | ||
610 | internal string errorMessage = null; | 617 | public string errorMessage = null; |
611 | 618 | ||
612 | internal List<Coord> coords; | 619 | public List<Coord> coords; |
613 | internal List<Face> faces; | 620 | public List<Face> faces; |
614 | internal List<Coord> vertexNormals; | 621 | public List<Coord> vertexNormals; |
615 | internal List<float> us; | 622 | public List<float> us; |
616 | internal List<UVCoord> faceUVs; | 623 | public List<UVCoord> faceUVs; |
617 | internal List<int> faceNumbers; | 624 | public List<int> faceNumbers; |
618 | 625 | ||
619 | // use these for making individual meshes for each prim face | 626 | // use these for making individual meshes for each prim face |
620 | internal List<int> outerCoordIndices = null; | 627 | public List<int> outerCoordIndices = null; |
621 | internal List<int> hollowCoordIndices = null; | 628 | public List<int> hollowCoordIndices = null; |
622 | internal List<int> cut1CoordIndices = null; | 629 | public List<int> cut1CoordIndices = null; |
623 | internal List<int> cut2CoordIndices = null; | 630 | public List<int> cut2CoordIndices = null; |
624 | 631 | ||
625 | internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); | 632 | public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); |
626 | internal Coord cutNormal1 = new Coord(); | 633 | public Coord cutNormal1 = new Coord(); |
627 | internal Coord cutNormal2 = new Coord(); | 634 | public Coord cutNormal2 = new Coord(); |
628 | 635 | ||
629 | internal int numOuterVerts = 0; | 636 | public int numOuterVerts = 0; |
630 | internal int numHollowVerts = 0; | 637 | public int numHollowVerts = 0; |
631 | 638 | ||
632 | internal int outerFaceNumber = -1; | 639 | public int outerFaceNumber = -1; |
633 | internal int hollowFaceNumber = -1; | 640 | public int hollowFaceNumber = -1; |
634 | 641 | ||
635 | internal bool calcVertexNormals = false; | 642 | public bool calcVertexNormals = false; |
636 | internal int bottomFaceNumber = 0; | 643 | public int bottomFaceNumber = 0; |
637 | internal int numPrimFaces = 0; | 644 | public int numPrimFaces = 0; |
638 | 645 | ||
639 | internal Profile() | 646 | public Profile() |
640 | { | 647 | { |
641 | this.coords = new List<Coord>(); | 648 | this.coords = new List<Coord>(); |
642 | this.faces = new List<Face>(); | 649 | this.faces = new List<Face>(); |
@@ -646,7 +653,7 @@ namespace PrimMesher | |||
646 | this.faceNumbers = new List<int>(); | 653 | this.faceNumbers = new List<int>(); |
647 | } | 654 | } |
648 | 655 | ||
649 | internal Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) | 656 | public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) |
650 | { | 657 | { |
651 | this.calcVertexNormals = calcVertexNormals; | 658 | this.calcVertexNormals = calcVertexNormals; |
652 | this.coords = new List<Coord>(); | 659 | this.coords = new List<Coord>(); |
@@ -657,7 +664,6 @@ namespace PrimMesher | |||
657 | this.faceNumbers = new List<int>(); | 664 | this.faceNumbers = new List<int>(); |
658 | 665 | ||
659 | Coord center = new Coord(0.0f, 0.0f, 0.0f); | 666 | Coord center = new Coord(0.0f, 0.0f, 0.0f); |
660 | //bool hasCenter = false; | ||
661 | 667 | ||
662 | List<Coord> hollowCoords = new List<Coord>(); | 668 | List<Coord> hollowCoords = new List<Coord>(); |
663 | List<Coord> hollowNormals = new List<Coord>(); | 669 | List<Coord> hollowNormals = new List<Coord>(); |
@@ -682,8 +688,8 @@ namespace PrimMesher | |||
682 | float yScale = 0.5f; | 688 | float yScale = 0.5f; |
683 | if (sides == 4) // corners of a square are sqrt(2) from center | 689 | if (sides == 4) // corners of a square are sqrt(2) from center |
684 | { | 690 | { |
685 | xScale = 0.707f; | 691 | xScale = 0.707107f; |
686 | yScale = 0.707f; | 692 | yScale = 0.707107f; |
687 | } | 693 | } |
688 | 694 | ||
689 | float startAngle = profileStart * twoPi; | 695 | float startAngle = profileStart * twoPi; |
@@ -724,7 +730,6 @@ namespace PrimMesher | |||
724 | else if (!simpleFace) | 730 | else if (!simpleFace) |
725 | { | 731 | { |
726 | this.coords.Add(center); | 732 | this.coords.Add(center); |
727 | //hasCenter = true; | ||
728 | if (this.calcVertexNormals) | 733 | if (this.calcVertexNormals) |
729 | this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); | 734 | this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); |
730 | this.us.Add(0.0f); | 735 | this.us.Add(0.0f); |
@@ -752,7 +757,10 @@ namespace PrimMesher | |||
752 | else | 757 | else |
753 | hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); | 758 | hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); |
754 | 759 | ||
755 | hollowUs.Add(angle.angle * hollow); | 760 | if (hollowSides == 4) |
761 | hollowUs.Add(angle.angle * hollow * 0.707107f); | ||
762 | else | ||
763 | hollowUs.Add(angle.angle * hollow); | ||
756 | } | 764 | } |
757 | } | 765 | } |
758 | } | 766 | } |
@@ -829,9 +837,6 @@ namespace PrimMesher | |||
829 | 837 | ||
830 | if (createFaces) | 838 | if (createFaces) |
831 | { | 839 | { |
832 | //int numOuterVerts = this.coords.Count; | ||
833 | //numOuterVerts = this.coords.Count; | ||
834 | //int numHollowVerts = hollowCoords.Count; | ||
835 | int numTotalVerts = this.numOuterVerts + this.numHollowVerts; | 840 | int numTotalVerts = this.numOuterVerts + this.numHollowVerts; |
836 | 841 | ||
837 | if (this.numOuterVerts == this.numHollowVerts) | 842 | if (this.numOuterVerts == this.numHollowVerts) |
@@ -993,11 +998,7 @@ namespace PrimMesher | |||
993 | if (startVert > 0) | 998 | if (startVert > 0) |
994 | this.faceNumbers.Add(-1); | 999 | this.faceNumbers.Add(-1); |
995 | for (int i = 0; i < this.numOuterVerts - 1; i++) | 1000 | for (int i = 0; i < this.numOuterVerts - 1; i++) |
996 | //this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum); | 1001 | this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); |
997 | this.faceNumbers.Add(sides < 5 && i < sides ? faceNum++ : faceNum); | ||
998 | |||
999 | //if (!hasHollow && !hasProfileCut) | ||
1000 | // this.bottomFaceNumber = faceNum++; | ||
1001 | 1002 | ||
1002 | this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); | 1003 | this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); |
1003 | 1004 | ||
@@ -1014,8 +1015,7 @@ namespace PrimMesher | |||
1014 | 1015 | ||
1015 | this.hollowFaceNumber = faceNum++; | 1016 | this.hollowFaceNumber = faceNum++; |
1016 | } | 1017 | } |
1017 | //if (hasProfileCut || hasHollow) | 1018 | |
1018 | // this.bottomFaceNumber = faceNum++; | ||
1019 | this.bottomFaceNumber = faceNum++; | 1019 | this.bottomFaceNumber = faceNum++; |
1020 | 1020 | ||
1021 | if (hasHollow && hasProfileCut) | 1021 | if (hasHollow && hasProfileCut) |
@@ -1030,19 +1030,19 @@ namespace PrimMesher | |||
1030 | 1030 | ||
1031 | } | 1031 | } |
1032 | 1032 | ||
1033 | internal void MakeFaceUVs() | 1033 | public void MakeFaceUVs() |
1034 | { | 1034 | { |
1035 | this.faceUVs = new List<UVCoord>(); | 1035 | this.faceUVs = new List<UVCoord>(); |
1036 | foreach (Coord c in this.coords) | 1036 | foreach (Coord c in this.coords) |
1037 | this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y)); | 1037 | this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | internal Profile Copy() | 1040 | public Profile Copy() |
1041 | { | 1041 | { |
1042 | return this.Copy(true); | 1042 | return this.Copy(true); |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | internal Profile Copy(bool needFaces) | 1045 | public Profile Copy(bool needFaces) |
1046 | { | 1046 | { |
1047 | Profile copy = new Profile(); | 1047 | Profile copy = new Profile(); |
1048 | 1048 | ||
@@ -1071,12 +1071,12 @@ namespace PrimMesher | |||
1071 | return copy; | 1071 | return copy; |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | internal void AddPos(Coord v) | 1074 | public void AddPos(Coord v) |
1075 | { | 1075 | { |
1076 | this.AddPos(v.X, v.Y, v.Z); | 1076 | this.AddPos(v.X, v.Y, v.Z); |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | internal void AddPos(float x, float y, float z) | 1079 | public void AddPos(float x, float y, float z) |
1080 | { | 1080 | { |
1081 | int i; | 1081 | int i; |
1082 | int numVerts = this.coords.Count; | 1082 | int numVerts = this.coords.Count; |
@@ -1092,7 +1092,7 @@ namespace PrimMesher | |||
1092 | } | 1092 | } |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | internal void AddRot(Quat q) | 1095 | public void AddRot(Quat q) |
1096 | { | 1096 | { |
1097 | int i; | 1097 | int i; |
1098 | int numVerts = this.coords.Count; | 1098 | int numVerts = this.coords.Count; |
@@ -1113,7 +1113,7 @@ namespace PrimMesher | |||
1113 | } | 1113 | } |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | internal void Scale(float x, float y) | 1116 | public void Scale(float x, float y) |
1117 | { | 1117 | { |
1118 | int i; | 1118 | int i; |
1119 | int numVerts = this.coords.Count; | 1119 | int numVerts = this.coords.Count; |
@@ -1131,7 +1131,7 @@ namespace PrimMesher | |||
1131 | /// <summary> | 1131 | /// <summary> |
1132 | /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices | 1132 | /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices |
1133 | /// </summary> | 1133 | /// </summary> |
1134 | internal void FlipNormals() | 1134 | public void FlipNormals() |
1135 | { | 1135 | { |
1136 | int i; | 1136 | int i; |
1137 | int numFaces = this.faces.Count; | 1137 | int numFaces = this.faces.Count; |
@@ -1171,7 +1171,7 @@ namespace PrimMesher | |||
1171 | } | 1171 | } |
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | internal void AddValue2FaceVertexIndices(int num) | 1174 | public void AddValue2FaceVertexIndices(int num) |
1175 | { | 1175 | { |
1176 | int numFaces = this.faces.Count; | 1176 | int numFaces = this.faces.Count; |
1177 | Face tmpFace; | 1177 | Face tmpFace; |
@@ -1186,7 +1186,7 @@ namespace PrimMesher | |||
1186 | } | 1186 | } |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | internal void AddValue2FaceNormalIndices(int num) | 1189 | public void AddValue2FaceNormalIndices(int num) |
1190 | { | 1190 | { |
1191 | if (this.calcVertexNormals) | 1191 | if (this.calcVertexNormals) |
1192 | { | 1192 | { |
@@ -1204,7 +1204,7 @@ namespace PrimMesher | |||
1204 | } | 1204 | } |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | internal void DumpRaw(String path, String name, String title) | 1207 | public void DumpRaw(String path, String name, String title) |
1208 | { | 1208 | { |
1209 | if (path == null) | 1209 | if (path == null) |
1210 | return; | 1210 | return; |
@@ -1261,6 +1261,15 @@ namespace PrimMesher | |||
1261 | 1261 | ||
1262 | public void Create(PathType pathType, int steps) | 1262 | public void Create(PathType pathType, int steps) |
1263 | { | 1263 | { |
1264 | if (this.taperX > 0.999f) | ||
1265 | this.taperX = 0.999f; | ||
1266 | if (this.taperX < -0.999f) | ||
1267 | this.taperX = -0.999f; | ||
1268 | if (this.taperY > 0.999f) | ||
1269 | this.taperY = 0.999f; | ||
1270 | if (this.taperY < -0.999f) | ||
1271 | this.taperY = -0.999f; | ||
1272 | |||
1264 | if (pathType == PathType.Linear || pathType == PathType.Flexible) | 1273 | if (pathType == PathType.Linear || pathType == PathType.Flexible) |
1265 | { | 1274 | { |
1266 | int step = 0; | 1275 | int step = 0; |
@@ -1273,12 +1282,12 @@ namespace PrimMesher | |||
1273 | 1282 | ||
1274 | float start = -0.5f; | 1283 | float start = -0.5f; |
1275 | float stepSize = length / (float)steps; | 1284 | float stepSize = length / (float)steps; |
1276 | float percentOfPathMultiplier = stepSize; | 1285 | float percentOfPathMultiplier = stepSize * 0.999999f; |
1277 | float xOffset = 0.0f; | 1286 | float xOffset = this.topShearX * this.pathCutBegin; |
1278 | float yOffset = 0.0f; | 1287 | float yOffset = this.topShearY * this.pathCutBegin; |
1279 | float zOffset = start; | 1288 | float zOffset = start; |
1280 | float xOffsetStepIncrement = this.topShearX / steps; | 1289 | float xOffsetStepIncrement = this.topShearX * length / steps; |
1281 | float yOffsetStepIncrement = this.topShearY / steps; | 1290 | float yOffsetStepIncrement = this.topShearY * length / steps; |
1282 | 1291 | ||
1283 | float percentOfPath = this.pathCutBegin; | 1292 | float percentOfPath = this.pathCutBegin; |
1284 | zOffset += percentOfPath; | 1293 | zOffset += percentOfPath; |
@@ -1573,13 +1582,6 @@ namespace PrimMesher | |||
1573 | this.hollow = 0.99f; | 1582 | this.hollow = 0.99f; |
1574 | if (hollow < 0.0f) | 1583 | if (hollow < 0.0f) |
1575 | this.hollow = 0.0f; | 1584 | this.hollow = 0.0f; |
1576 | |||
1577 | //if (sphereMode) | ||
1578 | // this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; | ||
1579 | //else | ||
1580 | // //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); | ||
1581 | // this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; | ||
1582 | //this.hasHollow = (this.hollow > 0.001f); | ||
1583 | } | 1585 | } |
1584 | 1586 | ||
1585 | /// <summary> | 1587 | /// <summary> |
@@ -1614,10 +1616,9 @@ namespace PrimMesher | |||
1614 | steps = (int)(steps * 4.5 * length); | 1616 | steps = (int)(steps * 4.5 * length); |
1615 | } | 1617 | } |
1616 | 1618 | ||
1617 | if (sphereMode) | 1619 | if (this.sphereMode) |
1618 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; | 1620 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; |
1619 | else | 1621 | else |
1620 | //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); | ||
1621 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; | 1622 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; |
1622 | this.hasHollow = (this.hollow > 0.001f); | 1623 | this.hasHollow = (this.hollow > 0.001f); |
1623 | 1624 | ||
@@ -1630,6 +1631,22 @@ namespace PrimMesher | |||
1630 | 1631 | ||
1631 | float hollow = this.hollow; | 1632 | float hollow = this.hollow; |
1632 | 1633 | ||
1634 | if (pathType == PathType.Circular) | ||
1635 | { | ||
1636 | needEndFaces = false; | ||
1637 | if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f) | ||
1638 | needEndFaces = true; | ||
1639 | else if (this.taperX != 0.0f || this.taperY != 0.0f) | ||
1640 | needEndFaces = true; | ||
1641 | else if (this.skew != 0.0f) | ||
1642 | needEndFaces = true; | ||
1643 | else if (twistTotal != 0.0f) | ||
1644 | needEndFaces = true; | ||
1645 | else if (this.radius != 0.0f) | ||
1646 | needEndFaces = true; | ||
1647 | } | ||
1648 | else needEndFaces = true; | ||
1649 | |||
1633 | // sanity checks | 1650 | // sanity checks |
1634 | float initialProfileRot = 0.0f; | 1651 | float initialProfileRot = 0.0f; |
1635 | if (pathType == PathType.Circular) | 1652 | if (pathType == PathType.Circular) |
@@ -1689,20 +1706,13 @@ namespace PrimMesher | |||
1689 | 1706 | ||
1690 | this.numPrimFaces = profile.numPrimFaces; | 1707 | this.numPrimFaces = profile.numPrimFaces; |
1691 | 1708 | ||
1692 | //profileOuterFaceNumber = profile.faceNumbers[0]; | 1709 | int cut1FaceNumber = profile.bottomFaceNumber + 1; |
1693 | //if (!needEndFaces) | 1710 | int cut2FaceNumber = cut1FaceNumber + 1; |
1694 | // profileOuterFaceNumber--; | 1711 | if (!needEndFaces) |
1695 | //profileOuterFaceNumber = needEndFaces ? 1 : 0; | 1712 | { |
1696 | 1713 | cut1FaceNumber -= 2; | |
1697 | 1714 | cut2FaceNumber -= 2; | |
1698 | //if (hasHollow) | 1715 | } |
1699 | //{ | ||
1700 | // if (needEndFaces) | ||
1701 | // profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts + 1]; | ||
1702 | // else | ||
1703 | // profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts] - 1; | ||
1704 | //} | ||
1705 | |||
1706 | 1716 | ||
1707 | profileOuterFaceNumber = profile.outerFaceNumber; | 1717 | profileOuterFaceNumber = profile.outerFaceNumber; |
1708 | if (!needEndFaces) | 1718 | if (!needEndFaces) |
@@ -1732,7 +1742,8 @@ namespace PrimMesher | |||
1732 | 1742 | ||
1733 | Coord lastCutNormal1 = new Coord(); | 1743 | Coord lastCutNormal1 = new Coord(); |
1734 | Coord lastCutNormal2 = new Coord(); | 1744 | Coord lastCutNormal2 = new Coord(); |
1735 | float lastV = 1.0f; | 1745 | float thisV = 0.0f; |
1746 | float lastV = 0.0f; | ||
1736 | 1747 | ||
1737 | Path path = new Path(); | 1748 | Path path = new Path(); |
1738 | path.twistBegin = twistBegin; | 1749 | path.twistBegin = twistBegin; |
@@ -1754,23 +1765,6 @@ namespace PrimMesher | |||
1754 | 1765 | ||
1755 | path.Create(pathType, steps); | 1766 | path.Create(pathType, steps); |
1756 | 1767 | ||
1757 | |||
1758 | if (pathType == PathType.Circular) | ||
1759 | { | ||
1760 | needEndFaces = false; | ||
1761 | if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f) | ||
1762 | needEndFaces = true; | ||
1763 | else if (this.taperX != 0.0f || this.taperY != 0.0f) | ||
1764 | needEndFaces = true; | ||
1765 | else if (this.skew != 0.0f) | ||
1766 | needEndFaces = true; | ||
1767 | else if (twistTotal != 0.0f) | ||
1768 | needEndFaces = true; | ||
1769 | else if (this.radius != 0.0f) | ||
1770 | needEndFaces = true; | ||
1771 | } | ||
1772 | else needEndFaces = true; | ||
1773 | |||
1774 | for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) | 1768 | for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) |
1775 | { | 1769 | { |
1776 | PathNode node = path.pathNodes[nodeIndex]; | 1770 | PathNode node = path.pathNodes[nodeIndex]; |
@@ -1784,7 +1778,7 @@ namespace PrimMesher | |||
1784 | { | 1778 | { |
1785 | newLayer.FlipNormals(); | 1779 | newLayer.FlipNormals(); |
1786 | 1780 | ||
1787 | // add the top faces to the viewerFaces list here | 1781 | // add the bottom faces to the viewerFaces list |
1788 | if (this.viewerMode) | 1782 | if (this.viewerMode) |
1789 | { | 1783 | { |
1790 | Coord faceNormal = newLayer.faceNormal; | 1784 | Coord faceNormal = newLayer.faceNormal; |
@@ -1811,6 +1805,13 @@ namespace PrimMesher | |||
1811 | newViewerFace.uv2 = newLayer.faceUVs[face.v2]; | 1805 | newViewerFace.uv2 = newLayer.faceUVs[face.v2]; |
1812 | newViewerFace.uv3 = newLayer.faceUVs[face.v3]; | 1806 | newViewerFace.uv3 = newLayer.faceUVs[face.v3]; |
1813 | 1807 | ||
1808 | if (pathType == PathType.Linear) | ||
1809 | { | ||
1810 | newViewerFace.uv1.Flip(); | ||
1811 | newViewerFace.uv2.Flip(); | ||
1812 | newViewerFace.uv3.Flip(); | ||
1813 | } | ||
1814 | |||
1814 | this.viewerFaces.Add(newViewerFace); | 1815 | this.viewerFaces.Add(newViewerFace); |
1815 | } | 1816 | } |
1816 | } | 1817 | } |
@@ -1835,7 +1836,10 @@ namespace PrimMesher | |||
1835 | // fill faces between layers | 1836 | // fill faces between layers |
1836 | 1837 | ||
1837 | int numVerts = newLayer.coords.Count; | 1838 | int numVerts = newLayer.coords.Count; |
1838 | Face newFace = new Face(); | 1839 | Face newFace1 = new Face(); |
1840 | Face newFace2 = new Face(); | ||
1841 | |||
1842 | thisV = 1.0f - node.percentOfPath; | ||
1839 | 1843 | ||
1840 | if (nodeIndex > 0) | 1844 | if (nodeIndex > 0) |
1841 | { | 1845 | { |
@@ -1853,14 +1857,23 @@ namespace PrimMesher | |||
1853 | 1857 | ||
1854 | int whichVert = i - startVert; | 1858 | int whichVert = i - startVert; |
1855 | 1859 | ||
1856 | newFace.v1 = i; | 1860 | newFace1.v1 = i; |
1857 | newFace.v2 = i - numVerts; | 1861 | newFace1.v2 = i - numVerts; |
1858 | newFace.v3 = iNext - numVerts; | 1862 | newFace1.v3 = iNext; |
1859 | this.faces.Add(newFace); | 1863 | |
1864 | newFace1.n1 = newFace1.v1; | ||
1865 | newFace1.n2 = newFace1.v2; | ||
1866 | newFace1.n3 = newFace1.v3; | ||
1867 | this.faces.Add(newFace1); | ||
1860 | 1868 | ||
1861 | newFace.v2 = iNext - numVerts; | 1869 | newFace2.v1 = iNext; |
1862 | newFace.v3 = iNext; | 1870 | newFace2.v2 = i - numVerts; |
1863 | this.faces.Add(newFace); | 1871 | newFace2.v3 = iNext - numVerts; |
1872 | |||
1873 | newFace2.n1 = newFace2.v1; | ||
1874 | newFace2.n2 = newFace2.v2; | ||
1875 | newFace2.n3 = newFace2.v3; | ||
1876 | this.faces.Add(newFace2); | ||
1864 | 1877 | ||
1865 | if (this.viewerMode) | 1878 | if (this.viewerMode) |
1866 | { | 1879 | { |
@@ -1873,10 +1886,16 @@ namespace PrimMesher | |||
1873 | ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); | 1886 | ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); |
1874 | ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); | 1887 | ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); |
1875 | 1888 | ||
1876 | float u1 = newLayer.us[whichVert]; | 1889 | int uIndex = whichVert; |
1890 | if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) | ||
1891 | { | ||
1892 | uIndex++; | ||
1893 | } | ||
1894 | |||
1895 | float u1 = newLayer.us[uIndex]; | ||
1877 | float u2 = 1.0f; | 1896 | float u2 = 1.0f; |
1878 | if (whichVert < newLayer.us.Count - 1) | 1897 | if (uIndex < (int)newLayer.us.Count - 1) |
1879 | u2 = newLayer.us[whichVert + 1]; | 1898 | u2 = newLayer.us[uIndex + 1]; |
1880 | 1899 | ||
1881 | if (whichVert == cut1Vert || whichVert == cut2Vert) | 1900 | if (whichVert == cut1Vert || whichVert == cut2Vert) |
1882 | { | 1901 | { |
@@ -1894,13 +1913,22 @@ namespace PrimMesher | |||
1894 | u1 -= (int)u1; | 1913 | u1 -= (int)u1; |
1895 | if (u2 < 0.1f) | 1914 | if (u2 < 0.1f) |
1896 | u2 = 1.0f; | 1915 | u2 = 1.0f; |
1897 | //this.profileOuterFaceNumber = primFaceNum; | ||
1898 | } | 1916 | } |
1899 | else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1) | 1917 | } |
1918 | |||
1919 | if (this.sphereMode) | ||
1920 | { | ||
1921 | if (whichVert != cut1Vert && whichVert != cut2Vert) | ||
1900 | { | 1922 | { |
1901 | u1 *= 2.0f; | 1923 | u1 = u1 * 2.0f - 1.0f; |
1902 | u2 *= 2.0f; | 1924 | u2 = u2 * 2.0f - 1.0f; |
1903 | //this.profileHollowFaceNumber = primFaceNum; | 1925 | |
1926 | if (whichVert >= newLayer.numOuterVerts) | ||
1927 | { | ||
1928 | u1 -= hollow; | ||
1929 | u2 -= hollow; | ||
1930 | } | ||
1931 | |||
1904 | } | 1932 | } |
1905 | } | 1933 | } |
1906 | 1934 | ||
@@ -1908,37 +1936,39 @@ namespace PrimMesher | |||
1908 | newViewerFace1.uv2.U = u1; | 1936 | newViewerFace1.uv2.U = u1; |
1909 | newViewerFace1.uv3.U = u2; | 1937 | newViewerFace1.uv3.U = u2; |
1910 | 1938 | ||
1911 | newViewerFace1.uv1.V = 1.0f - node.percentOfPath; | 1939 | newViewerFace1.uv1.V = thisV; |
1912 | newViewerFace1.uv2.V = lastV; | 1940 | newViewerFace1.uv2.V = lastV; |
1913 | newViewerFace1.uv3.V = lastV; | 1941 | newViewerFace1.uv3.V = thisV; |
1914 | 1942 | ||
1915 | newViewerFace2.uv1.U = u1; | 1943 | newViewerFace2.uv1.U = u2; |
1916 | newViewerFace2.uv2.U = u2; | 1944 | newViewerFace2.uv2.U = u1; |
1917 | newViewerFace2.uv3.U = u2; | 1945 | newViewerFace2.uv3.U = u2; |
1918 | 1946 | ||
1919 | newViewerFace2.uv1.V = 1.0f - node.percentOfPath; | 1947 | newViewerFace2.uv1.V = thisV; |
1920 | newViewerFace2.uv2.V = lastV; | 1948 | newViewerFace2.uv2.V = lastV; |
1921 | newViewerFace2.uv3.V = 1.0f - node.percentOfPath; | 1949 | newViewerFace2.uv3.V = lastV; |
1922 | 1950 | ||
1923 | newViewerFace1.v1 = this.coords[i]; | 1951 | newViewerFace1.v1 = this.coords[newFace1.v1]; |
1924 | newViewerFace1.v2 = this.coords[i - numVerts]; | 1952 | newViewerFace1.v2 = this.coords[newFace1.v2]; |
1925 | newViewerFace1.v3 = this.coords[iNext - numVerts]; | 1953 | newViewerFace1.v3 = this.coords[newFace1.v3]; |
1926 | 1954 | ||
1927 | newViewerFace2.v1 = this.coords[i]; | 1955 | newViewerFace2.v1 = this.coords[newFace2.v1]; |
1928 | newViewerFace2.v2 = this.coords[iNext - numVerts]; | 1956 | newViewerFace2.v2 = this.coords[newFace2.v2]; |
1929 | newViewerFace2.v3 = this.coords[iNext]; | 1957 | newViewerFace2.v3 = this.coords[newFace2.v3]; |
1930 | 1958 | ||
1931 | newViewerFace1.coordIndex1 = i; | 1959 | newViewerFace1.coordIndex1 = newFace1.v1; |
1932 | newViewerFace1.coordIndex2 = i - numVerts; | 1960 | newViewerFace1.coordIndex2 = newFace1.v2; |
1933 | newViewerFace1.coordIndex3 = iNext - numVerts; | 1961 | newViewerFace1.coordIndex3 = newFace1.v3; |
1934 | 1962 | ||
1935 | newViewerFace2.coordIndex1 = i; | 1963 | newViewerFace2.coordIndex1 = newFace2.v1; |
1936 | newViewerFace2.coordIndex2 = iNext - numVerts; | 1964 | newViewerFace2.coordIndex2 = newFace2.v2; |
1937 | newViewerFace2.coordIndex3 = iNext; | 1965 | newViewerFace2.coordIndex3 = newFace2.v3; |
1938 | 1966 | ||
1939 | // profile cut faces | 1967 | // profile cut faces |
1940 | if (whichVert == cut1Vert) | 1968 | if (whichVert == cut1Vert) |
1941 | { | 1969 | { |
1970 | newViewerFace1.primFaceNumber = cut1FaceNumber; | ||
1971 | newViewerFace2.primFaceNumber = cut1FaceNumber; | ||
1942 | newViewerFace1.n1 = newLayer.cutNormal1; | 1972 | newViewerFace1.n1 = newLayer.cutNormal1; |
1943 | newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; | 1973 | newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; |
1944 | 1974 | ||
@@ -1947,10 +1977,14 @@ namespace PrimMesher | |||
1947 | } | 1977 | } |
1948 | else if (whichVert == cut2Vert) | 1978 | else if (whichVert == cut2Vert) |
1949 | { | 1979 | { |
1980 | newViewerFace1.primFaceNumber = cut2FaceNumber; | ||
1981 | newViewerFace2.primFaceNumber = cut2FaceNumber; | ||
1950 | newViewerFace1.n1 = newLayer.cutNormal2; | 1982 | newViewerFace1.n1 = newLayer.cutNormal2; |
1951 | newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2; | 1983 | newViewerFace1.n2 = lastCutNormal2; |
1984 | newViewerFace1.n3 = lastCutNormal2; | ||
1952 | 1985 | ||
1953 | newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2; | 1986 | newViewerFace2.n1 = newLayer.cutNormal2; |
1987 | newViewerFace2.n3 = newLayer.cutNormal2; | ||
1954 | newViewerFace2.n2 = lastCutNormal2; | 1988 | newViewerFace2.n2 = lastCutNormal2; |
1955 | } | 1989 | } |
1956 | 1990 | ||
@@ -1963,13 +1997,13 @@ namespace PrimMesher | |||
1963 | } | 1997 | } |
1964 | else | 1998 | else |
1965 | { | 1999 | { |
1966 | newViewerFace1.n1 = this.normals[i]; | 2000 | newViewerFace1.n1 = this.normals[newFace1.n1]; |
1967 | newViewerFace1.n2 = this.normals[i - numVerts]; | 2001 | newViewerFace1.n2 = this.normals[newFace1.n2]; |
1968 | newViewerFace1.n3 = this.normals[iNext - numVerts]; | 2002 | newViewerFace1.n3 = this.normals[newFace1.n3]; |
1969 | 2003 | ||
1970 | newViewerFace2.n1 = this.normals[i]; | 2004 | newViewerFace2.n1 = this.normals[newFace2.n1]; |
1971 | newViewerFace2.n2 = this.normals[iNext - numVerts]; | 2005 | newViewerFace2.n2 = this.normals[newFace2.n2]; |
1972 | newViewerFace2.n3 = this.normals[iNext]; | 2006 | newViewerFace2.n3 = this.normals[newFace2.n3]; |
1973 | } | 2007 | } |
1974 | } | 2008 | } |
1975 | 2009 | ||
@@ -1982,14 +2016,13 @@ namespace PrimMesher | |||
1982 | 2016 | ||
1983 | lastCutNormal1 = newLayer.cutNormal1; | 2017 | lastCutNormal1 = newLayer.cutNormal1; |
1984 | lastCutNormal2 = newLayer.cutNormal2; | 2018 | lastCutNormal2 = newLayer.cutNormal2; |
1985 | lastV = 1.0f - node.percentOfPath; | 2019 | lastV = thisV; |
1986 | 2020 | ||
1987 | if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) | 2021 | if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) |
1988 | { | 2022 | { |
1989 | // add the top faces to the viewerFaces list here | 2023 | // add the top faces to the viewerFaces list here |
1990 | Coord faceNormal = newLayer.faceNormal; | 2024 | Coord faceNormal = newLayer.faceNormal; |
1991 | ViewerFace newViewerFace = new ViewerFace(); | 2025 | ViewerFace newViewerFace = new ViewerFace(0); |
1992 | newViewerFace.primFaceNumber = 0; | ||
1993 | int numFaces = newLayer.faces.Count; | 2026 | int numFaces = newLayer.faces.Count; |
1994 | List<Face> faces = newLayer.faces; | 2027 | List<Face> faces = newLayer.faces; |
1995 | 2028 | ||
@@ -2012,6 +2045,13 @@ namespace PrimMesher | |||
2012 | newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; | 2045 | newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; |
2013 | newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; | 2046 | newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; |
2014 | 2047 | ||
2048 | if (pathType == PathType.Linear) | ||
2049 | { | ||
2050 | newViewerFace.uv1.Flip(); | ||
2051 | newViewerFace.uv2.Flip(); | ||
2052 | newViewerFace.uv3.Flip(); | ||
2053 | } | ||
2054 | |||
2015 | this.viewerFaces.Add(newViewerFace); | 2055 | this.viewerFaces.Add(newViewerFace); |
2016 | } | 2056 | } |
2017 | } | 2057 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fed3122..a43a8bb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -517,15 +517,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
517 | return LSL_Vector.Norm(v); | 517 | return LSL_Vector.Norm(v); |
518 | } | 518 | } |
519 | 519 | ||
520 | public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) | 520 | private double VecDist(LSL_Vector a, LSL_Vector b) |
521 | { | 521 | { |
522 | m_host.AddScriptLPS(1); | ||
523 | double dx = a.x - b.x; | 522 | double dx = a.x - b.x; |
524 | double dy = a.y - b.y; | 523 | double dy = a.y - b.y; |
525 | double dz = a.z - b.z; | 524 | double dz = a.z - b.z; |
526 | return Math.Sqrt(dx * dx + dy * dy + dz * dz); | 525 | return Math.Sqrt(dx * dx + dy * dy + dz * dz); |
527 | } | 526 | } |
528 | 527 | ||
528 | public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) | ||
529 | { | ||
530 | m_host.AddScriptLPS(1); | ||
531 | return VecDist(a, b); | ||
532 | } | ||
533 | |||
529 | //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke | 534 | //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke |
530 | 535 | ||
531 | // Utility function for llRot2Euler | 536 | // Utility function for llRot2Euler |
@@ -1391,6 +1396,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1391 | } | 1396 | } |
1392 | } | 1397 | } |
1393 | 1398 | ||
1399 | private bool IsPhysical() | ||
1400 | { | ||
1401 | return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics); | ||
1402 | } | ||
1403 | |||
1394 | public LSL_Integer llGetStatus(int status) | 1404 | public LSL_Integer llGetStatus(int status) |
1395 | { | 1405 | { |
1396 | m_host.AddScriptLPS(1); | 1406 | m_host.AddScriptLPS(1); |
@@ -1398,11 +1408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1398 | switch (status) | 1408 | switch (status) |
1399 | { | 1409 | { |
1400 | case ScriptBaseClass.STATUS_PHYSICS: | 1410 | case ScriptBaseClass.STATUS_PHYSICS: |
1401 | if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics) | 1411 | return IsPhysical() ? 1 : 0; |
1402 | { | ||
1403 | return 1; | ||
1404 | } | ||
1405 | return 0; | ||
1406 | 1412 | ||
1407 | case ScriptBaseClass.STATUS_PHANTOM: | 1413 | case ScriptBaseClass.STATUS_PHANTOM: |
1408 | if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) | 1414 | if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) |
@@ -2155,11 +2161,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2155 | { | 2161 | { |
2156 | m_host.AddScriptLPS(1); | 2162 | m_host.AddScriptLPS(1); |
2157 | 2163 | ||
2158 | SetPos(m_host, pos); | 2164 | SetPos(m_host, pos, true); |
2159 | 2165 | ||
2160 | ScriptSleep(200); | 2166 | ScriptSleep(200); |
2161 | } | 2167 | } |
2162 | 2168 | ||
2169 | /// <summary> | ||
2170 | /// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos | ||
2171 | /// Documentation indicates that the use of x/y coordinates up to 10 meters outside the bounds of a region will work but do not specify what happens if there is no adjacent region for the object to move into. | ||
2172 | /// Uses the RegionSize constant here rather than hard-coding 266.0 to alert any developer modifying OpenSim to support variable-sized regions that this method will need tweaking. | ||
2173 | /// </summary> | ||
2174 | /// <param name="pos"></param> | ||
2175 | /// <returns>1 if successful, 0 otherwise.</returns> | ||
2176 | public LSL_Integer llSetRegionPos(LSL_Vector pos) | ||
2177 | { | ||
2178 | m_host.AddScriptLPS(1); | ||
2179 | |||
2180 | // BEGIN WORKAROUND | ||
2181 | // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. | ||
2182 | // | ||
2183 | // This workaround is to prevent silent failure of this function. | ||
2184 | // According to the specification on the SL Wiki, providing a position outside of the | ||
2185 | if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) | ||
2186 | { | ||
2187 | return 0; | ||
2188 | } | ||
2189 | // END WORK AROUND | ||
2190 | else if ( // this is not part of the workaround if-block because it's not related to the workaround. | ||
2191 | IsPhysical() || | ||
2192 | m_host.ParentGroup.IsAttachment || // return FALSE if attachment | ||
2193 | ( | ||
2194 | pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. | ||
2195 | pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. | ||
2196 | pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. | ||
2197 | pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. | ||
2198 | pos.z > 4096 // return FALSE if altitude than 4096m | ||
2199 | ) | ||
2200 | ) | ||
2201 | { | ||
2202 | return 0; | ||
2203 | } | ||
2204 | |||
2205 | // if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range. | ||
2206 | // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read. | ||
2207 | |||
2208 | Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; | ||
2209 | LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y); | ||
2210 | LandData there = World.GetLandData((float)pos.x, (float)pos.y); | ||
2211 | |||
2212 | // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits. | ||
2213 | |||
2214 | bool sameParcel = here.GlobalID == there.GlobalID; | ||
2215 | |||
2216 | if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) | ||
2217 | { | ||
2218 | return 0; | ||
2219 | } | ||
2220 | |||
2221 | SetPos(m_host.ParentGroup.RootPart, pos, false); | ||
2222 | |||
2223 | return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; | ||
2224 | } | ||
2225 | |||
2163 | // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) | 2226 | // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) |
2164 | // note linked setpos is capped "differently" | 2227 | // note linked setpos is capped "differently" |
2165 | private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end) | 2228 | private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end) |
@@ -2191,55 +2254,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2191 | return real_vec; | 2254 | return real_vec; |
2192 | } | 2255 | } |
2193 | 2256 | ||
2194 | public LSL_Integer llSetRegionPos(LSL_Vector pos) | 2257 | /// <summary> |
2195 | { | 2258 | /// set object position, optionally capping the distance. |
2196 | return new LSL_Integer(SetRegionPos(m_host, pos)); | 2259 | /// </summary> |
2197 | } | 2260 | /// <param name="part"></param> |
2198 | 2261 | /// <param name="targetPos"></param> | |
2199 | protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos) | 2262 | /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> |
2200 | { | 2263 | protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) |
2201 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2202 | return 0; | ||
2203 | |||
2204 | SceneObjectGroup grp = part.ParentGroup; | ||
2205 | |||
2206 | if (grp.IsAttachment) | ||
2207 | return 0; | ||
2208 | |||
2209 | if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical) | ||
2210 | return 0; | ||
2211 | |||
2212 | if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f) | ||
2213 | return 0; | ||
2214 | |||
2215 | float constrainedX = (float)targetPos.x; | ||
2216 | float constrainedY = (float)targetPos.y; | ||
2217 | |||
2218 | if (constrainedX < 0.0f) | ||
2219 | constrainedX = 0.0f; | ||
2220 | if (constrainedY < 0.0f) | ||
2221 | constrainedY = 0.0f; | ||
2222 | if (constrainedX >= (float)Constants.RegionSize) | ||
2223 | constrainedX = (float)Constants.RegionSize - 0.1f; | ||
2224 | if (constrainedY >= (float)Constants.RegionSize) | ||
2225 | constrainedY = (float)Constants.RegionSize -0.1f; | ||
2226 | |||
2227 | float ground = World.GetGroundHeight(constrainedX, constrainedY); | ||
2228 | |||
2229 | if (targetPos.z < ground) | ||
2230 | targetPos.z = ground; | ||
2231 | |||
2232 | Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z); | ||
2233 | |||
2234 | if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest)) | ||
2235 | return 0; | ||
2236 | |||
2237 | grp.UpdateGroupPosition(dest); | ||
2238 | |||
2239 | return 1; | ||
2240 | } | ||
2241 | |||
2242 | protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) | ||
2243 | { | 2264 | { |
2244 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 2265 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
2245 | return; | 2266 | return; |