diff options
author | Magnuz Binder | 2015-05-10 20:01:50 +0200 |
---|---|---|
committer | dahlia | 2015-05-12 15:40:42 -0700 |
commit | d348f871612c5f241f33885604391d1f30a416bc (patch) | |
tree | b163a65e5fa6337877f9848024bd6760e37108b4 /OpenSim/Region | |
parent | Disable the "show threadpool calls active" console command for now. (diff) | |
download | opensim-SC-d348f871612c5f241f33885604391d1f30a416bc.zip opensim-SC-d348f871612c5f241f33885604391d1f30a416bc.tar.gz opensim-SC-d348f871612c5f241f33885604391d1f30a416bc.tar.bz2 opensim-SC-d348f871612c5f241f33885604391d1f30a416bc.tar.xz |
Patch llCastRay fully simplified to V3.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 429 |
1 files changed, 217 insertions, 212 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c90f015..089a5a8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -221,15 +221,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
221 | protected float m_primSafetyCoeffX = 2.414214f; | 221 | protected float m_primSafetyCoeffX = 2.414214f; |
222 | protected float m_primSafetyCoeffY = 2.414214f; | 222 | protected float m_primSafetyCoeffY = 2.414214f; |
223 | protected float m_primSafetyCoeffZ = 1.618034f; | 223 | protected float m_primSafetyCoeffZ = 1.618034f; |
224 | protected bool m_useCastRayV3 = false; | ||
224 | protected float m_floatToleranceInCastRay = 0.000001f; | 225 | protected float m_floatToleranceInCastRay = 0.000001f; |
225 | protected float m_floatTolerance2InCastRay = 0.0001f; | 226 | protected float m_floatTolerance2InCastRay = 0.0001f; |
227 | protected DetailLevel m_primLodInCastRay = DetailLevel.Medium; | ||
228 | protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium; | ||
229 | protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest; | ||
230 | protected DetailLevel m_avatarLodInCastRay = DetailLevel.Medium; | ||
226 | protected int m_maxHitsInCastRay = 16; | 231 | protected int m_maxHitsInCastRay = 16; |
227 | protected int m_maxHitsPerPrimInCastRay = 16; | 232 | protected int m_maxHitsPerPrimInCastRay = 16; |
228 | protected int m_maxHitsPerObjectInCastRay = 16; | 233 | protected int m_maxHitsPerObjectInCastRay = 16; |
229 | protected bool m_detectExitsInCastRay = false; | 234 | protected bool m_detectExitsInCastRay = false; |
230 | protected bool m_filterPartsInCastRay = false; | 235 | protected bool m_filterPartsInCastRay = false; |
231 | protected bool m_doAttachmentsInCastRay = false; | 236 | protected bool m_doAttachmentsInCastRay = false; |
232 | protected bool m_useCastRayV1 = true; | ||
233 | 237 | ||
234 | //An array of HTTP/1.1 headers that are not allowed to be used | 238 | //An array of HTTP/1.1 headers that are not allowed to be used |
235 | //as custom headers by llHTTPRequest. | 239 | //as custom headers by llHTTPRequest. |
@@ -336,15 +340,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
336 | m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX); | 340 | m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX); |
337 | m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY); | 341 | m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY); |
338 | m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ); | 342 | m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ); |
343 | m_useCastRayV3 = lslConfig.GetBoolean("UseLlCastRayV3", m_useCastRayV3); | ||
339 | m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay); | 344 | m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay); |
340 | m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay); | 345 | m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay); |
346 | m_primLodInCastRay = (DetailLevel)lslConfig.GetInt("PrimDetailLevelInLlCastRay", (int)m_primLodInCastRay); | ||
347 | m_sculptLodInCastRay = (DetailLevel)lslConfig.GetInt("SculptDetailLevelInLlCastRay", (int)m_sculptLodInCastRay); | ||
348 | m_meshLodInCastRay = (DetailLevel)lslConfig.GetInt("MeshDetailLevelInLlCastRay", (int)m_meshLodInCastRay); | ||
349 | m_avatarLodInCastRay = (DetailLevel)lslConfig.GetInt("AvatarDetailLevelInLlCastRay", (int)m_avatarLodInCastRay); | ||
341 | m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay); | 350 | m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay); |
342 | m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); | 351 | m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); |
343 | m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); | 352 | m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); |
344 | m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); | 353 | m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); |
345 | m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay); | 354 | m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay); |
346 | m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); | 355 | m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); |
347 | m_useCastRayV1 = lslConfig.GetBoolean("UseLlCastRayV1", m_useCastRayV1); | ||
348 | } | 356 | } |
349 | 357 | ||
350 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; | 358 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; |
@@ -13811,8 +13819,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13811 | return contacts[0]; | 13819 | return contacts[0]; |
13812 | } | 13820 | } |
13813 | 13821 | ||
13814 | public LSL_List llCastRayV1(LSL_Vector start, LSL_Vector end, LSL_List options) | 13822 | public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) |
13815 | { | 13823 | { |
13824 | // Use llCastRay V3 if configured | ||
13825 | if (m_useCastRayV3) | ||
13826 | return llCastRayV3(start, end, options); | ||
13827 | |||
13816 | LSL_List list = new LSL_List(); | 13828 | LSL_List list = new LSL_List(); |
13817 | 13829 | ||
13818 | m_host.AddScriptLPS(1); | 13830 | m_host.AddScriptLPS(1); |
@@ -14003,29 +14015,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14003 | } | 14015 | } |
14004 | 14016 | ||
14005 | /// <summary> | 14017 | /// <summary> |
14006 | /// Full implementation of llCastRay similar to SL 2015-04-21. | 14018 | /// Implementation of llCastRay similar to SL 2015-04-21. |
14007 | /// http://wiki.secondlife.com/wiki/LlCastRay | 14019 | /// http://wiki.secondlife.com/wiki/LlCastRay |
14008 | /// Uses pure geometry, bounding shapes, meshing and no physics | 14020 | /// Uses pure geometry, bounding shapes, meshing and no physics |
14009 | /// for prims, sculpts, meshes, avatars and terrain. | 14021 | /// for prims, sculpts, meshes, avatars and terrain. |
14010 | /// Implements all flags, reject types and data flags. | 14022 | /// Implements all flags, reject types and data flags. |
14011 | /// Can handle both objects/groups and prims/parts, by config. | 14023 | /// Can handle both objects/groups and prims/parts, by config. |
14012 | /// May give poor results with multi-part meshes where "root" | 14024 | /// May sometimes be inaccurate owing to calculation precision, |
14013 | /// part doesn't dominate, owing to "guessed" bounding boxes. | 14025 | /// meshing detail level and a bug in libopenmetaverse PrimMesher. |
14014 | /// May sometimes be inaccurate owing to calculation precision | ||
14015 | /// and a bug in libopenmetaverse PrimMesher. | ||
14016 | /// </summary> | 14026 | /// </summary> |
14017 | public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) | 14027 | public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options) |
14018 | { | 14028 | { |
14019 | // Use llCastRay v1 if configured | ||
14020 | if (m_useCastRayV1) | ||
14021 | return llCastRayV1(start, end, options); | ||
14022 | |||
14023 | // Initialize | 14029 | // Initialize |
14024 | m_host.AddScriptLPS(1); | 14030 | m_host.AddScriptLPS(1); |
14025 | List<RayHit> rayHits = new List<RayHit>(); | 14031 | List<RayHit> rayHits = new List<RayHit>(); |
14026 | LSL_List result = new LSL_List(); | 14032 | LSL_List result = new LSL_List(); |
14027 | float tol = m_floatToleranceInCastRay; | 14033 | float tol = m_floatToleranceInCastRay; |
14028 | float tol2 = m_floatTolerance2InCastRay; | 14034 | Vector3 pos1Ray = start; |
14035 | Vector3 pos2Ray = end; | ||
14029 | 14036 | ||
14030 | // Get input options | 14037 | // Get input options |
14031 | int rejectTypes = 0; | 14038 | int rejectTypes = 0; |
@@ -14054,25 +14061,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14054 | bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0); | 14061 | bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0); |
14055 | 14062 | ||
14056 | // Calculate some basic parameters | 14063 | // Calculate some basic parameters |
14057 | Vector3 ray = end - start; | 14064 | Vector3 vecRay = pos2Ray - pos1Ray; |
14058 | float rayLength = ray.Length(); | 14065 | float rayLength = vecRay.Length(); |
14059 | 14066 | ||
14060 | // Try to get a mesher and return failure if none or degenerate ray | 14067 | // Try to get a mesher and return failure if none, degenerate ray, or max 0 hits |
14061 | IRendering primMesher = null; | 14068 | IRendering primMesher = null; |
14062 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); | 14069 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); |
14063 | if (renderers.Count < 1 || rayLength < tol) | 14070 | if (renderers.Count < 1 || rayLength < tol || m_maxHitsInCastRay < 1) |
14064 | { | 14071 | { |
14065 | result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN)); | 14072 | result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN)); |
14066 | return result; | 14073 | return result; |
14067 | } | 14074 | } |
14068 | primMesher = RenderingLoader.LoadRenderer(renderers[0]); | 14075 | primMesher = RenderingLoader.LoadRenderer(renderers[0]); |
14069 | 14076 | ||
14070 | // Used to translate and rotate world so ray is along negative Z axis from origo and | ||
14071 | // calculations mostly simplified to a 2D projecttion on the X-Y plane | ||
14072 | Vector3 posProj = new Vector3(-start); | ||
14073 | Quaternion rotProj = Vector3.RotationBetween(ray, new Vector3(0.0f, 0.0f, -1.0f)); | ||
14074 | Quaternion rotBack = Quaternion.Inverse(rotProj); | ||
14075 | |||
14076 | // Iterate over all objects/groups and prims/parts in region | 14077 | // Iterate over all objects/groups and prims/parts in region |
14077 | World.ForEachSOG( | 14078 | World.ForEachSOG( |
14078 | delegate(SceneObjectGroup group) | 14079 | delegate(SceneObjectGroup group) |
@@ -14115,51 +14116,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14115 | if (!doPart) | 14116 | if (!doPart) |
14116 | continue; | 14117 | continue; |
14117 | } | 14118 | } |
14118 | // Parse prim/part if passed filters | ||
14119 | 14119 | ||
14120 | // Estimate bounding box from size box | 14120 | // Parse prim/part and project ray if passed filters |
14121 | Vector3 scaleSafe = part.Scale; | 14121 | Vector3 scalePart = part.Scale; |
14122 | if (!part.Shape.SculptEntry) | 14122 | Vector3 posPart = part.GetWorldPosition(); |
14123 | scaleSafe = scaleSafe * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); | 14123 | Quaternion rotPart = part.GetWorldRotation(); |
14124 | Quaternion rotPartInv = Quaternion.Inverse(rotPart); | ||
14125 | Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; | ||
14126 | Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; | ||
14124 | 14127 | ||
14125 | // Filter parts by bounding shapes | 14128 | // Filter parts by shape bounding boxes |
14126 | Vector3 posPartRel = part.GetWorldPosition() + posProj; | 14129 | Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f); |
14127 | Vector3 posPartProj = posPartRel * rotProj; | 14130 | if (!part.Shape.SculptEntry) |
14128 | if (InBoundingShapes(ray, rayLength, scaleSafe, posPartRel, posPartProj, rotProj)) | 14131 | shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); |
14132 | shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol)); | ||
14133 | if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) | ||
14129 | { | 14134 | { |
14130 | // Prepare data needed to check for ray hits | 14135 | // Prepare data needed to check for ray hits |
14131 | RayTrans rayTrans = new RayTrans(); | 14136 | RayTrans rayTrans = new RayTrans(); |
14132 | rayTrans.PartId = part.UUID; | 14137 | rayTrans.PartId = part.UUID; |
14133 | rayTrans.GroupId = part.ParentGroup.UUID; | 14138 | rayTrans.GroupId = part.ParentGroup.UUID; |
14134 | rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0; | 14139 | rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0; |
14135 | rayTrans.Scale = part.Scale; | 14140 | rayTrans.ScalePart = scalePart; |
14136 | rayTrans.PositionPartProj = posPartProj; | 14141 | rayTrans.PositionPart = posPart; |
14137 | rayTrans.PositionProj = posProj; | 14142 | rayTrans.RotationPart = rotPart; |
14138 | rayTrans.RotationPartProj = rotProj * part.GetWorldRotation(); | 14143 | rayTrans.ShapeNeedsEnds = true; |
14139 | rayTrans.RotationBack = rotBack; | 14144 | rayTrans.Position1Ray = pos1Ray; |
14140 | rayTrans.NeedsEnds = true; | 14145 | rayTrans.Position1RayProj = pos1RayProj; |
14141 | rayTrans.RayLength = rayLength; | 14146 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; |
14142 | rayTrans.Tolerance = tol; | ||
14143 | rayTrans.Tolerance2 = tol2; | ||
14144 | 14147 | ||
14145 | // Make an OMV prim to be able to mesh part | 14148 | // Make an OMV prim to be able to mesh part |
14146 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPartProj, rayTrans.RotationPartProj); | 14149 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); |
14147 | byte[] sculptAsset = null; | 14150 | byte[] sculptAsset = null; |
14148 | if (omvPrim.Sculpt != null) | 14151 | if (omvPrim.Sculpt != null) |
14149 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | 14152 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); |
14153 | FacetedMesh mesh = null; | ||
14150 | 14154 | ||
14151 | // When part is mesh, get and check mesh | 14155 | // When part is mesh, get mesh and check for hits |
14152 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | 14156 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) |
14153 | { | 14157 | { |
14154 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); | 14158 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); |
14155 | FacetedMesh mesh = null; | 14159 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh); |
14156 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh); | ||
14157 | meshAsset = null; | 14160 | meshAsset = null; |
14158 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14159 | mesh = null; | ||
14160 | } | 14161 | } |
14161 | 14162 | ||
14162 | // When part is sculpt, create and check mesh | 14163 | // When part is sculpt, create mesh and check for hits |
14163 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | 14164 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. |
14164 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | 14165 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) |
14165 | { | 14166 | { |
@@ -14169,15 +14170,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14169 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); | 14170 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); |
14170 | if (sculpt != null) | 14171 | if (sculpt != null) |
14171 | { | 14172 | { |
14172 | SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium); | 14173 | mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay); |
14173 | sculpt.Dispose(); | 14174 | sculpt.Dispose(); |
14174 | AddRayInSimpleMesh(mesh, rayTrans, ref rayHits); | ||
14175 | mesh = null; | ||
14176 | } | 14175 | } |
14177 | } | 14176 | } |
14178 | } | 14177 | } |
14179 | 14178 | ||
14180 | // When part is prim, create and check mesh | 14179 | // When part is prim, create mesh and check for hits |
14181 | else if (omvPrim.Sculpt == null) | 14180 | else if (omvPrim.Sculpt == null) |
14182 | { | 14181 | { |
14183 | if ( | 14182 | if ( |
@@ -14186,12 +14185,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14186 | omvPrim.PrimData.PathSkew == 0.0 && | 14185 | omvPrim.PrimData.PathSkew == 0.0 && |
14187 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 | 14186 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 |
14188 | ) | 14187 | ) |
14189 | rayTrans.NeedsEnds = false; | 14188 | rayTrans.ShapeNeedsEnds = false; |
14190 | SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); | 14189 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay); |
14191 | AddRayInSimpleMesh(mesh, rayTrans, ref rayHits); | ||
14192 | mesh = null; | ||
14193 | } | 14190 | } |
14194 | 14191 | ||
14192 | // Check mesh for ray hits | ||
14193 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14194 | mesh = null; | ||
14195 | } | 14195 | } |
14196 | } | 14196 | } |
14197 | } | 14197 | } |
@@ -14205,38 +14205,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14205 | World.ForEachRootScenePresence( | 14205 | World.ForEachRootScenePresence( |
14206 | delegate (ScenePresence sp) | 14206 | delegate (ScenePresence sp) |
14207 | { | 14207 | { |
14208 | // Parse avatar | ||
14209 | |||
14210 | // Get bounding box | 14208 | // Get bounding box |
14211 | Vector3 lower; | 14209 | Vector3 lower; |
14212 | Vector3 upper; | 14210 | Vector3 upper; |
14213 | BoundingBoxOfScenePresence(sp, out lower, out upper); | 14211 | BoundingBoxOfScenePresence(sp, out lower, out upper); |
14214 | Vector3 scale = upper - lower; | 14212 | // Parse avatar |
14215 | 14213 | Vector3 scalePart = upper - lower; | |
14216 | // Filter avatars by bounding shapes | 14214 | Vector3 posPart = sp.AbsolutePosition; |
14217 | Vector3 posPartRel = sp.AbsolutePosition + posProj + (lower + upper) * 0.5f * sp.Rotation; | 14215 | Quaternion rotPart = sp.GetWorldRotation(); |
14218 | Vector3 posPartProj = posPartRel * rotProj; | 14216 | Quaternion rotPartInv = Quaternion.Inverse(rotPart); |
14219 | if (InBoundingShapes(ray, rayLength, scale, posPartRel, posPartProj, rotProj)) | 14217 | posPart = posPart + (lower + upper) * 0.5f * rotPart; |
14218 | // Project ray | ||
14219 | Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; | ||
14220 | Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; | ||
14221 | |||
14222 | // Filter avatars by shape bounding boxes | ||
14223 | Vector3 shapeBoxMax = new Vector3(0.5f + tol, 0.5f + tol, 0.5f + tol); | ||
14224 | if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) | ||
14220 | { | 14225 | { |
14221 | // Prepare data needed to check for ray hits | 14226 | // Prepare data needed to check for ray hits |
14222 | RayTrans rayTrans = new RayTrans(); | 14227 | RayTrans rayTrans = new RayTrans(); |
14223 | rayTrans.PartId = sp.UUID; | 14228 | rayTrans.PartId = sp.UUID; |
14224 | rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID; | 14229 | rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID; |
14225 | rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0; | 14230 | rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0; |
14226 | rayTrans.Scale = scale; | 14231 | rayTrans.ScalePart = scalePart; |
14227 | rayTrans.PositionPartProj = posPartProj; | 14232 | rayTrans.PositionPart = posPart; |
14228 | rayTrans.PositionProj = posProj; | 14233 | rayTrans.RotationPart = rotPart; |
14229 | rayTrans.RotationPartProj = rotProj * sp.Rotation; | 14234 | rayTrans.ShapeNeedsEnds = false; |
14230 | rayTrans.RotationBack = rotBack; | 14235 | rayTrans.Position1Ray = pos1Ray; |
14231 | rayTrans.NeedsEnds = false; | 14236 | rayTrans.Position1RayProj = pos1RayProj; |
14232 | rayTrans.RayLength = rayLength; | 14237 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; |
14233 | rayTrans.Tolerance = tol; | ||
14234 | rayTrans.Tolerance2 = tol2; | ||
14235 | 14238 | ||
14236 | // Make OMV prim, create and check mesh | 14239 | // Make OMV prim, create and check mesh |
14237 | Primitive omvPrim = MakeOpenMetaversePrim(scale, posPartProj, rayTrans.RotationPartProj, ScriptBaseClass.PRIM_TYPE_SPHERE); | 14240 | PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere(); |
14238 | SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); | 14241 | prim.Scale = scalePart; |
14239 | AddRayInSimpleMesh(mesh, rayTrans, ref rayHits); | 14242 | Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart); |
14243 | FacetedMesh mesh = primMesher.GenerateFacetedMesh(omvPrim, m_meshLodInCastRay); | ||
14244 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14240 | mesh = null; | 14245 | mesh = null; |
14241 | } | 14246 | } |
14242 | } | 14247 | } |
@@ -14248,32 +14253,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14248 | { | 14253 | { |
14249 | // Parse terrain | 14254 | // Parse terrain |
14250 | 14255 | ||
14251 | // Mesh terrain and check projected bounding box | 14256 | // Mesh terrain and check bounding box |
14252 | Vector3 posPartProj = posProj * rotProj; | ||
14253 | Quaternion rotPartProj = rotProj; | ||
14254 | Vector3 lower; | 14257 | Vector3 lower; |
14255 | Vector3 upper; | 14258 | Vector3 upper; |
14256 | List<Tri> triangles = TrisFromHeightmapUnderRay(start, end, out lower, out upper); | 14259 | List<Tri> triangles = TrisFromHeightmapUnderRay(pos1Ray, pos2Ray, out lower, out upper); |
14257 | Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); | 14260 | lower.Z -= tol; |
14258 | Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue); | 14261 | upper.Z += tol; |
14259 | int dummy = 0; | 14262 | if ((pos1Ray.Z >= lower.Z || pos2Ray.Z >= lower.Z) && (pos1Ray.Z <= upper.Z || pos2Ray.Z <= upper.Z)) |
14260 | AddBoundingBoxOfSimpleBox(lower, upper, posPartProj, rotPartProj, true, ref lowerBox, ref upperBox, ref dummy); | ||
14261 | if (lowerBox.X <= tol && lowerBox.Y <= tol && lowerBox.Z <= tol && upperBox.X >= -tol && upperBox.Y >= -tol && upperBox.Z >= -rayLength - tol) | ||
14262 | { | 14263 | { |
14263 | // Prepare data needed to check for ray hits | 14264 | // Prepare data needed to check for ray hits |
14264 | RayTrans rayTrans = new RayTrans(); | 14265 | RayTrans rayTrans = new RayTrans(); |
14265 | rayTrans.PartId = UUID.Zero; | 14266 | rayTrans.PartId = UUID.Zero; |
14266 | rayTrans.GroupId = UUID.Zero; | 14267 | rayTrans.GroupId = UUID.Zero; |
14267 | rayTrans.Link = 0; | 14268 | rayTrans.Link = 0; |
14268 | rayTrans.Scale = new Vector3 (1.0f, 1.0f, 1.0f); | 14269 | rayTrans.ScalePart = new Vector3 (1.0f, 1.0f, 1.0f); |
14269 | rayTrans.PositionPartProj = posPartProj; | 14270 | rayTrans.PositionPart = Vector3.Zero; |
14270 | rayTrans.PositionProj = posProj; | 14271 | rayTrans.RotationPart = Quaternion.Identity; |
14271 | rayTrans.RotationPartProj = rotPartProj; | 14272 | rayTrans.ShapeNeedsEnds = true; |
14272 | rayTrans.RotationBack = rotBack; | 14273 | rayTrans.Position1Ray = pos1Ray; |
14273 | rayTrans.NeedsEnds = true; | 14274 | rayTrans.Position1RayProj = pos1Ray; |
14274 | rayTrans.RayLength = rayLength; | 14275 | rayTrans.VectorRayProj = vecRay; |
14275 | rayTrans.Tolerance = tol; | ||
14276 | rayTrans.Tolerance2 = tol2; | ||
14277 | 14276 | ||
14278 | // Check mesh | 14277 | // Check mesh |
14279 | AddRayInTris(triangles, rayTrans, ref rayHits); | 14278 | AddRayInTris(triangles, rayTrans, ref rayHits); |
@@ -14358,15 +14357,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14358 | public UUID PartId; | 14357 | public UUID PartId; |
14359 | public UUID GroupId; | 14358 | public UUID GroupId; |
14360 | public int Link; | 14359 | public int Link; |
14361 | public Vector3 Scale; | 14360 | public Vector3 ScalePart; |
14362 | public Vector3 PositionPartProj; | 14361 | public Vector3 PositionPart; |
14363 | public Vector3 PositionProj; | 14362 | public Quaternion RotationPart; |
14364 | public Quaternion RotationPartProj; | 14363 | public bool ShapeNeedsEnds; |
14365 | public Quaternion RotationBack; | 14364 | public Vector3 Position1Ray; |
14366 | public bool NeedsEnds; | 14365 | public Vector3 Position1RayProj; |
14367 | public float RayLength; | 14366 | public Vector3 VectorRayProj; |
14368 | public float Tolerance; | ||
14369 | public float Tolerance2; | ||
14370 | } | 14367 | } |
14371 | 14368 | ||
14372 | /// <summary> | 14369 | /// <summary> |
@@ -14383,21 +14380,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14383 | } | 14380 | } |
14384 | 14381 | ||
14385 | /// <summary> | 14382 | /// <summary> |
14386 | /// Helper to parse SimpleMesh for ray hits. | 14383 | /// Helper to check if a ray intersects a shape bounding box. |
14387 | /// </summary> | 14384 | /// </summary> |
14388 | private void AddRayInSimpleMesh(SimpleMesh mesh, RayTrans rayTrans, ref List<RayHit> rayHits) | 14385 | private bool RayIntersectsShapeBox(Vector3 pos1RayProj, Vector3 pos2RayProj, Vector3 shapeBoxMax) |
14389 | { | 14386 | { |
14390 | if (mesh != null) | 14387 | // Skip if ray can't intersect bounding box; |
14388 | Vector3 rayBoxProjMin = Vector3.Min(pos1RayProj, pos2RayProj); | ||
14389 | Vector3 rayBoxProjMax = Vector3.Max(pos1RayProj, pos2RayProj); | ||
14390 | if ( | ||
14391 | rayBoxProjMin.X > shapeBoxMax.X || rayBoxProjMin.Y > shapeBoxMax.Y || rayBoxProjMin.Z > shapeBoxMax.Z || | ||
14392 | rayBoxProjMax.X < -shapeBoxMax.X || rayBoxProjMax.Y < -shapeBoxMax.Y || rayBoxProjMax.Z < -shapeBoxMax.Z | ||
14393 | ) | ||
14394 | return false; | ||
14395 | |||
14396 | // Check if ray intersect any bounding box side | ||
14397 | int sign = 0; | ||
14398 | float dist = 0.0f; | ||
14399 | Vector3 posProj = Vector3.Zero; | ||
14400 | Vector3 vecRayProj = pos2RayProj - pos1RayProj; | ||
14401 | |||
14402 | // Check both X sides unless ray is parallell to them | ||
14403 | if (Math.Abs(vecRayProj.X) > m_floatToleranceInCastRay) | ||
14404 | { | ||
14405 | for (sign = -1; sign <= 1; sign += 2) | ||
14406 | { | ||
14407 | dist = ((float)sign * shapeBoxMax.X - pos1RayProj.X) / vecRayProj.X; | ||
14408 | posProj = pos1RayProj + vecRayProj * dist; | ||
14409 | if (Math.Abs(posProj.Y) <= shapeBoxMax.Y && Math.Abs(posProj.Z) <= shapeBoxMax.Z) | ||
14410 | return true; | ||
14411 | } | ||
14412 | } | ||
14413 | |||
14414 | // Check both Y sides unless ray is parallell to them | ||
14415 | if (Math.Abs(vecRayProj.Y) > m_floatToleranceInCastRay) | ||
14391 | { | 14416 | { |
14392 | for (int i = 0; i < mesh.Indices.Count; i += 3) | 14417 | for (sign = -1; sign <= 1; sign += 2) |
14393 | { | 14418 | { |
14394 | Tri triangle = new Tri(); | 14419 | dist = ((float)sign * shapeBoxMax.Y - pos1RayProj.Y) / vecRayProj.Y; |
14395 | triangle.p1 = mesh.Vertices[mesh.Indices[i]].Position; | 14420 | posProj = pos1RayProj + vecRayProj * dist; |
14396 | triangle.p2 = mesh.Vertices[mesh.Indices[i + 1]].Position; | 14421 | if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Z) <= shapeBoxMax.Z) |
14397 | triangle.p3 = mesh.Vertices[mesh.Indices[i + 2]].Position; | 14422 | return true; |
14398 | AddRayInTri(triangle, rayTrans, ref rayHits); | ||
14399 | } | 14423 | } |
14400 | } | 14424 | } |
14425 | |||
14426 | // Check both Z sides unless ray is parallell to them | ||
14427 | if (Math.Abs(vecRayProj.Z) > m_floatToleranceInCastRay) | ||
14428 | { | ||
14429 | for (sign = -1; sign <= 1; sign += 2) | ||
14430 | { | ||
14431 | dist = ((float)sign * shapeBoxMax.Z - pos1RayProj.Z) / vecRayProj.Z; | ||
14432 | posProj = pos1RayProj + vecRayProj * dist; | ||
14433 | if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Y) <= shapeBoxMax.Y) | ||
14434 | return true; | ||
14435 | } | ||
14436 | } | ||
14437 | |||
14438 | // No hits on bounding box so return false | ||
14439 | return false; | ||
14401 | } | 14440 | } |
14402 | 14441 | ||
14403 | /// <summary> | 14442 | /// <summary> |
@@ -14409,7 +14448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14409 | { | 14448 | { |
14410 | foreach (Face face in mesh.Faces) | 14449 | foreach (Face face in mesh.Faces) |
14411 | { | 14450 | { |
14412 | for (int i = 0; i <face.Indices.Count; i += 3) | 14451 | for (int i = 0; i < face.Indices.Count; i += 3) |
14413 | { | 14452 | { |
14414 | Tri triangle = new Tri(); | 14453 | Tri triangle = new Tri(); |
14415 | triangle.p1 = face.Vertices[face.Indices[i]].Position; | 14454 | triangle.p1 = face.Vertices[face.Indices[i]].Position; |
@@ -14435,23 +14474,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14435 | /// <summary> | 14474 | /// <summary> |
14436 | /// Helper to add ray hit in a Tri (triangle). | 14475 | /// Helper to add ray hit in a Tri (triangle). |
14437 | /// </summary> | 14476 | /// </summary> |
14438 | private void AddRayInTri(Tri triangle, RayTrans rayTrans, ref List<RayHit> rayHits) | 14477 | private void AddRayInTri(Tri triProj, RayTrans rayTrans, ref List<RayHit> rayHits) |
14439 | { | 14478 | { |
14440 | // Check for hit in triangle | 14479 | // Check for hit in triangle |
14441 | float distance; | 14480 | Vector3 posHitProj; |
14442 | Vector3 posHit; | 14481 | Vector3 normalProj; |
14443 | Vector3 normal; | 14482 | if (HitRayInTri(triProj, rayTrans.Position1RayProj, rayTrans.VectorRayProj, out posHitProj, out normalProj)) |
14444 | if (HitRayInTri(triangle, rayTrans, out distance, out posHit, out normal)) | 14483 | { |
14445 | { | 14484 | // Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) face plane through shape center |
14446 | // Project hit part back to normal coordinate system | 14485 | if (Math.Abs(Vector3.Dot(posHitProj, normalProj)) < m_floatToleranceInCastRay && !rayTrans.ShapeNeedsEnds) |
14447 | Vector3 posPart = rayTrans.PositionPartProj * rayTrans.RotationBack - rayTrans.PositionProj; | ||
14448 | // Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) faces plane through shape center | ||
14449 | if (Math.Abs(Vector3.Dot(posPart, normal) - Vector3.Dot(posHit, normal)) < rayTrans.Tolerance && !rayTrans.NeedsEnds) | ||
14450 | return; | 14486 | return; |
14451 | // Remove duplicate hits at triangle edges and intersections | 14487 | |
14488 | // Transform hit and normal to region coordinate system | ||
14489 | Vector3 posHit = rayTrans.PositionPart + (posHitProj * rayTrans.ScalePart) * rayTrans.RotationPart; | ||
14490 | Vector3 normal = Vector3.Normalize((normalProj * rayTrans.ScalePart) * rayTrans.RotationPart); | ||
14491 | |||
14492 | // Remove duplicate hits at triangle intersections | ||
14493 | float distance = Vector3.Distance(rayTrans.Position1Ray, posHit); | ||
14452 | for (int i = rayHits.Count - 1; i >= 0; i--) | 14494 | for (int i = rayHits.Count - 1; i >= 0; i--) |
14453 | { | 14495 | { |
14454 | if (rayHits[i].PartId == rayTrans.PartId && Math.Abs(rayHits[i].Distance - distance) < rayTrans.Tolerance2) | 14496 | if (rayHits[i].PartId != rayTrans.PartId) |
14497 | break; | ||
14498 | if (Math.Abs(rayHits[i].Distance - distance) < m_floatTolerance2InCastRay) | ||
14455 | return; | 14499 | return; |
14456 | } | 14500 | } |
14457 | 14501 | ||
@@ -14468,76 +14512,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14468 | } | 14512 | } |
14469 | 14513 | ||
14470 | /// <summary> | 14514 | /// <summary> |
14471 | /// Helper to find ray hit in a Tri (triangle). | 14515 | /// Helper to find ray hit in triangle |
14472 | /// </summary> | 14516 | /// </summary> |
14473 | private bool HitRayInTri(Tri triangle, RayTrans rayTrans, out float distance, out Vector3 posHit, out Vector3 normal) | 14517 | bool HitRayInTri(Tri triProj, Vector3 pos1RayProj, Vector3 vecRayProj, out Vector3 posHitProj, out Vector3 normalProj) |
14474 | { | 14518 | { |
14475 | // Initialize | 14519 | float tol = m_floatToleranceInCastRay; |
14476 | distance = 0.0f; | 14520 | posHitProj = Vector3.Zero; |
14477 | posHit = Vector3.Zero; | 14521 | |
14478 | normal = Vector3.Zero; | 14522 | // Calculate triangle edge vectors |
14479 | float tol = rayTrans.Tolerance; | 14523 | Vector3 vec1Proj = triProj.p2 - triProj.p1; |
14480 | 14524 | Vector3 vec2Proj = triProj.p3 - triProj.p2; | |
14481 | // Project triangle on X-Y plane | 14525 | Vector3 vec3Proj = triProj.p1 - triProj.p3; |
14482 | Vector3 pos1 = triangle.p1 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj; | ||
14483 | Vector3 pos2 = triangle.p2 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj; | ||
14484 | Vector3 pos3 = triangle.p3 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj; | ||
14485 | |||
14486 | // Check if ray/origo inside triangle bounding rectangle | ||
14487 | Vector3 lower = Vector3.Min(pos1, Vector3.Min(pos2, pos3)); | ||
14488 | Vector3 upper = Vector3.Max(pos1, Vector3.Max(pos2, pos3)); | ||
14489 | if (lower.X > tol || lower.Y > tol || lower.Z > tol || upper.X < -tol || upper.Y < -tol || upper.Z < -rayTrans.RayLength - tol) | ||
14490 | return false; | ||
14491 | 14526 | ||
14492 | // Check if ray/origo inside every edge or reverse "outside" every edge on exit | 14527 | // Calculate triangle normal |
14493 | float dist; | 14528 | normalProj = Vector3.Cross(vec1Proj, vec2Proj); |
14494 | bool inside = true; | 14529 | |
14495 | bool outside = true; | 14530 | // Skip if degenerate triangle or ray parallell with triangle plane |
14496 | Vector3 vec1 = pos2 - pos1; | 14531 | float divisor = Vector3.Dot(vecRayProj, normalProj); |
14497 | dist = pos1.X * vec1.Y - pos1.Y * vec1.X; | 14532 | if (Math.Abs(divisor) < tol) |
14498 | if (dist < -tol) | ||
14499 | inside = false; | ||
14500 | if (dist > tol) | ||
14501 | outside = false; | ||
14502 | Vector3 vec2 = pos3 - pos2; | ||
14503 | dist = pos2.X * vec2.Y - pos2.Y * vec2.X; | ||
14504 | if (dist < -tol) | ||
14505 | inside = false; | ||
14506 | if (dist > tol) | ||
14507 | outside = false; | ||
14508 | Vector3 vec3 = pos1 - pos3; | ||
14509 | dist = pos3.X * vec3.Y - pos3.Y * vec3.X; | ||
14510 | if (dist < -tol) | ||
14511 | inside = false; | ||
14512 | if (dist > tol) | ||
14513 | outside = false; | ||
14514 | |||
14515 | // Skip if ray/origo outside | ||
14516 | if (!inside && !(outside && m_detectExitsInCastRay)) | ||
14517 | return false; | 14533 | return false; |
14518 | 14534 | ||
14519 | // Calculate normal | 14535 | // Skip if exit and not configured to detect |
14520 | Vector3 normalProj = Vector3.Cross(vec1, vec2); | 14536 | if (divisor > tol && !m_detectExitsInCastRay) |
14521 | float normalLength = normalProj.Length(); | ||
14522 | // Skip if degenerate triangle | ||
14523 | if (normalLength < tol) | ||
14524 | return false; | 14537 | return false; |
14525 | normalProj = normalProj / normalLength; | 14538 | |
14526 | // Skip if ray parallell to triangle plane | 14539 | // Skip if outside ray ends |
14527 | if (Math.Abs(normalProj.Z) < tol) | 14540 | float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor; |
14541 | if (distanceProj < -tol || distanceProj > 1 + tol) | ||
14528 | return false; | 14542 | return false; |
14529 | 14543 | ||
14530 | // Calculate distance | 14544 | // Calculate hit position in triangle |
14531 | distance = Vector3.Dot(normalProj, pos2) / normalProj.Z * -1.0f; | 14545 | posHitProj = pos1RayProj + vecRayProj * distanceProj; |
14532 | // Skip if outside ray | 14546 | |
14533 | if (distance < -tol || distance > rayTrans.RayLength + tol) | 14547 | // Skip if outside triangle bounding box |
14548 | Vector3 triProjMin = Vector3.Min(Vector3.Min(triProj.p1, triProj.p2), triProj.p3); | ||
14549 | Vector3 triProjMax = Vector3.Max(Vector3.Max(triProj.p1, triProj.p2), triProj.p3); | ||
14550 | if ( | ||
14551 | posHitProj.X < triProjMin.X - tol || posHitProj.Y < triProjMin.Y - tol || posHitProj.Z < triProjMin.Z - tol || | ||
14552 | posHitProj.X > triProjMax.X + tol || posHitProj.Y > triProjMax.Y + tol || posHitProj.Z > triProjMax.Z + tol | ||
14553 | ) | ||
14534 | return false; | 14554 | return false; |
14535 | 14555 | ||
14536 | // Calculate projected hit position | 14556 | // Skip if outside triangle |
14537 | Vector3 posHitProj = new Vector3(0.0f, 0.0f, -distance); | 14557 | if ( |
14538 | // Project hit back to normal coordinate system | 14558 | Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol || |
14539 | posHit = posHitProj * rayTrans.RotationBack - rayTrans.PositionProj; | 14559 | Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol || |
14540 | normal = normalProj * rayTrans.RotationBack; | 14560 | Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol |
14561 | ) | ||
14562 | return false; | ||
14563 | |||
14564 | // Return hit | ||
14541 | return true; | 14565 | return true; |
14542 | } | 14566 | } |
14543 | 14567 | ||
@@ -14660,24 +14684,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14660 | y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); | 14684 | y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); |
14661 | Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]); | 14685 | Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]); |
14662 | // Adjust bounding box | 14686 | // Adjust bounding box |
14663 | zLower = Math.Min(zLower, pos1.Z); | 14687 | zLower = Math.Min(zLower, pos2.Z); |
14664 | zUpper = Math.Max(zUpper, pos1.Z); | 14688 | zUpper = Math.Max(zUpper, pos2.Z); |
14665 | 14689 | ||
14666 | // Corner 3 of 1x1 rectangle | 14690 | // Corner 3 of 1x1 rectangle |
14667 | x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); | 14691 | x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); |
14668 | y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); | 14692 | y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); |
14669 | Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]); | 14693 | Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]); |
14670 | // Adjust bounding box | 14694 | // Adjust bounding box |
14671 | zLower = Math.Min(zLower, pos1.Z); | 14695 | zLower = Math.Min(zLower, pos3.Z); |
14672 | zUpper = Math.Max(zUpper, pos1.Z); | 14696 | zUpper = Math.Max(zUpper, pos3.Z); |
14673 | 14697 | ||
14674 | // Corner 4 of 1x1 rectangle | 14698 | // Corner 4 of 1x1 rectangle |
14675 | x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); | 14699 | x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); |
14676 | y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); | 14700 | y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); |
14677 | Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]); | 14701 | Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]); |
14678 | // Adjust bounding box | 14702 | // Adjust bounding box |
14679 | zLower = Math.Min(zLower, pos1.Z); | 14703 | zLower = Math.Min(zLower, pos4.Z); |
14680 | zUpper = Math.Max(zUpper, pos1.Z); | 14704 | zUpper = Math.Max(zUpper, pos4.Z); |
14681 | 14705 | ||
14682 | // Add triangle 1 | 14706 | // Add triangle 1 |
14683 | Tri triangle1 = new Tri(); | 14707 | Tri triangle1 = new Tri(); |
@@ -14695,25 +14719,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14695 | } | 14719 | } |
14696 | 14720 | ||
14697 | /// <summary> | 14721 | /// <summary> |
14698 | /// Helper to check if a ray intersects bounding shapes. | ||
14699 | /// </summary> | ||
14700 | private bool InBoundingShapes(Vector3 ray, float rayLength, Vector3 scale, Vector3 posPartRel, Vector3 posPartProj, Quaternion rotProj) | ||
14701 | { | ||
14702 | float tol = m_floatToleranceInCastRay; | ||
14703 | |||
14704 | // Check if ray intersects projected bounding box | ||
14705 | Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); | ||
14706 | Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue); | ||
14707 | int dummy = 0; | ||
14708 | AddBoundingBoxOfSimpleBox(scale * -0.5f, scale * 0.5f, posPartProj, rotProj, true, ref lowerBox, ref upperBox, ref dummy); | ||
14709 | if (lowerBox.X > tol || lowerBox.Y > tol || lowerBox.Z > tol || upperBox.X < -tol || upperBox.Y < -tol || upperBox.Z < -rayLength - tol) | ||
14710 | return false; | ||
14711 | |||
14712 | // Passed bounding shape filters, so return true | ||
14713 | return true; | ||
14714 | } | ||
14715 | |||
14716 | /// <summary> | ||
14717 | /// Helper to get link number for a UUID. | 14722 | /// Helper to get link number for a UUID. |
14718 | /// </summary> | 14723 | /// </summary> |
14719 | private int UUID2LinkNumber(SceneObjectPart part, UUID id) | 14724 | private int UUID2LinkNumber(SceneObjectPart part, UUID id) |