diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 143 |
1 files changed, 104 insertions, 39 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d75afb6..e769834 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -223,8 +223,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
223 | protected float m_primSafetyCoeffY = 2.414214f; | 223 | protected float m_primSafetyCoeffY = 2.414214f; |
224 | protected float m_primSafetyCoeffZ = 1.618034f; | 224 | protected float m_primSafetyCoeffZ = 1.618034f; |
225 | protected bool m_useCastRayV3 = false; | 225 | protected bool m_useCastRayV3 = false; |
226 | protected float m_floatToleranceInCastRay = 0.000001f; | 226 | protected float m_floatToleranceInCastRay = 0.00001f; |
227 | protected float m_floatTolerance2InCastRay = 0.0001f; | 227 | protected float m_floatTolerance2InCastRay = 0.001f; |
228 | protected DetailLevel m_primLodInCastRay = DetailLevel.Medium; | 228 | protected DetailLevel m_primLodInCastRay = DetailLevel.Medium; |
229 | protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium; | 229 | protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium; |
230 | protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest; | 230 | protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest; |
@@ -241,6 +241,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
241 | protected int m_msMinInCastRay = 2; | 241 | protected int m_msMinInCastRay = 2; |
242 | protected int m_msMaxInCastRay = 40; | 242 | protected int m_msMaxInCastRay = 40; |
243 | protected static List<CastRayCall> m_castRayCalls = new List<CastRayCall>(); | 243 | protected static List<CastRayCall> m_castRayCalls = new List<CastRayCall>(); |
244 | protected bool m_useMeshCacheInCastRay = true; | ||
245 | protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>(); | ||
244 | 246 | ||
245 | //An array of HTTP/1.1 headers that are not allowed to be used | 247 | //An array of HTTP/1.1 headers that are not allowed to be used |
246 | //as custom headers by llHTTPRequest. | 248 | //as custom headers by llHTTPRequest. |
@@ -365,6 +367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
365 | m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay); | 367 | m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay); |
366 | m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay); | 368 | m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay); |
367 | m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay); | 369 | m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay); |
370 | m_useMeshCacheInCastRay = lslConfig.GetBoolean("UseMeshCacheInLlCastRay", m_useMeshCacheInCastRay); | ||
368 | } | 371 | } |
369 | 372 | ||
370 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; | 373 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; |
@@ -14240,50 +14243,85 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14240 | rayTrans.Position1RayProj = pos1RayProj; | 14243 | rayTrans.Position1RayProj = pos1RayProj; |
14241 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; | 14244 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; |
14242 | 14245 | ||
14243 | // Make an OMV prim to be able to mesh part | 14246 | // Get detail level depending on type |
14244 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); | 14247 | int lod = 0; |
14245 | byte[] sculptAsset = null; | 14248 | // Mesh detail level |
14246 | if (omvPrim.Sculpt != null) | 14249 | if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh) |
14247 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | 14250 | lod = (int)m_meshLodInCastRay; |
14251 | // Sculpt detail level | ||
14252 | else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh) | ||
14253 | lod = (int)m_sculptLodInCastRay; | ||
14254 | // Shape detail level | ||
14255 | else if (!part.Shape.SculptEntry) | ||
14256 | lod = (int)m_primLodInCastRay; | ||
14257 | |||
14258 | // Try to get cached mesh if configured | ||
14259 | ulong meshKey = 0; | ||
14248 | FacetedMesh mesh = null; | 14260 | FacetedMesh mesh = null; |
14249 | 14261 | if (m_useMeshCacheInCastRay) | |
14250 | // When part is mesh, get mesh and check for hits | ||
14251 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
14252 | { | 14262 | { |
14253 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); | 14263 | meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod)); |
14254 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh); | 14264 | lock (m_cachedMeshes) |
14255 | meshAsset = null; | 14265 | { |
14266 | m_cachedMeshes.TryGetValue(meshKey, out mesh); | ||
14267 | } | ||
14256 | } | 14268 | } |
14257 | 14269 | ||
14258 | // When part is sculpt, create mesh and check for hits | 14270 | // Create mesh if no cached mesh |
14259 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | 14271 | if (mesh == null) |
14260 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | ||
14261 | { | 14272 | { |
14262 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | 14273 | // Make an OMV prim to be able to mesh part |
14263 | if (imgDecoder != null) | 14274 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); |
14275 | byte[] sculptAsset = null; | ||
14276 | if (omvPrim.Sculpt != null) | ||
14277 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | ||
14278 | |||
14279 | // When part is mesh, get mesh | ||
14280 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
14264 | { | 14281 | { |
14265 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); | 14282 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); |
14266 | if (sculpt != null) | 14283 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh); |
14284 | meshAsset = null; | ||
14285 | } | ||
14286 | |||
14287 | // When part is sculpt, create mesh | ||
14288 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | ||
14289 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | ||
14290 | { | ||
14291 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | ||
14292 | if (imgDecoder != null) | ||
14267 | { | 14293 | { |
14268 | mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay); | 14294 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); |
14269 | sculpt.Dispose(); | 14295 | if (sculpt != null) |
14296 | { | ||
14297 | mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay); | ||
14298 | sculpt.Dispose(); | ||
14299 | } | ||
14270 | } | 14300 | } |
14301 | } | ||
14302 | |||
14303 | // When part is shape, create mesh | ||
14304 | else if (omvPrim.Sculpt == null) | ||
14305 | { | ||
14306 | if ( | ||
14307 | omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 && | ||
14308 | omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 && | ||
14309 | omvPrim.PrimData.PathSkew == 0.0 && | ||
14310 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 | ||
14311 | ) | ||
14312 | rayTrans.ShapeNeedsEnds = false; | ||
14313 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay); | ||
14271 | } | 14314 | } |
14272 | } | ||
14273 | 14315 | ||
14274 | // When part is prim, create mesh and check for hits | 14316 | // Cache mesh if configured |
14275 | else if (omvPrim.Sculpt == null) | 14317 | if (m_useMeshCacheInCastRay && mesh != null) |
14276 | { | 14318 | { |
14277 | if ( | 14319 | lock(m_cachedMeshes) |
14278 | omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 && | 14320 | { |
14279 | omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 && | 14321 | m_cachedMeshes.Add(meshKey, mesh); |
14280 | omvPrim.PrimData.PathSkew == 0.0 && | 14322 | } |
14281 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 | 14323 | } |
14282 | ) | ||
14283 | rayTrans.ShapeNeedsEnds = false; | ||
14284 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay); | ||
14285 | } | 14324 | } |
14286 | |||
14287 | // Check mesh for ray hits | 14325 | // Check mesh for ray hits |
14288 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | 14326 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); |
14289 | mesh = null; | 14327 | mesh = null; |
@@ -14331,11 +14369,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14331 | rayTrans.Position1RayProj = pos1RayProj; | 14369 | rayTrans.Position1RayProj = pos1RayProj; |
14332 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; | 14370 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; |
14333 | 14371 | ||
14334 | // Make OMV prim, create and check mesh | 14372 | // Try to get cached mesh if configured |
14335 | PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere(); | 14373 | PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere(); |
14336 | prim.Scale = scalePart; | 14374 | int lod = (int)m_avatarLodInCastRay; |
14337 | Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart); | 14375 | ulong meshKey = prim.GetMeshKey(Vector3.One, (float)(4 << lod)); |
14338 | FacetedMesh mesh = primMesher.GenerateFacetedMesh(omvPrim, m_meshLodInCastRay); | 14376 | FacetedMesh mesh = null; |
14377 | if (m_useMeshCacheInCastRay) | ||
14378 | { | ||
14379 | lock (m_cachedMeshes) | ||
14380 | { | ||
14381 | m_cachedMeshes.TryGetValue(meshKey, out mesh); | ||
14382 | } | ||
14383 | } | ||
14384 | |||
14385 | // Create mesh if no cached mesh | ||
14386 | if (mesh == null) | ||
14387 | { | ||
14388 | // Make OMV prim and create mesh | ||
14389 | prim.Scale = scalePart; | ||
14390 | Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart); | ||
14391 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_avatarLodInCastRay); | ||
14392 | |||
14393 | // Cache mesh if configured | ||
14394 | if (m_useMeshCacheInCastRay && mesh != null) | ||
14395 | { | ||
14396 | lock(m_cachedMeshes) | ||
14397 | { | ||
14398 | m_cachedMeshes.Add(meshKey, mesh); | ||
14399 | } | ||
14400 | } | ||
14401 | } | ||
14402 | |||
14403 | // Check mesh for ray hits | ||
14339 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | 14404 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); |
14340 | mesh = null; | 14405 | mesh = null; |
14341 | } | 14406 | } |