Use own mesh cache in llCastRay V3 after throttling.
Signed-off-by: Michael Cerquoni <nebadon2025@gmail.com>fsassets
parent
7d26815d0e
commit
fdc383a843
|
@ -223,8 +223,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
protected float m_primSafetyCoeffY = 2.414214f;
|
protected float m_primSafetyCoeffY = 2.414214f;
|
||||||
protected float m_primSafetyCoeffZ = 1.618034f;
|
protected float m_primSafetyCoeffZ = 1.618034f;
|
||||||
protected bool m_useCastRayV3 = false;
|
protected bool m_useCastRayV3 = false;
|
||||||
protected float m_floatToleranceInCastRay = 0.000001f;
|
protected float m_floatToleranceInCastRay = 0.00001f;
|
||||||
protected float m_floatTolerance2InCastRay = 0.0001f;
|
protected float m_floatTolerance2InCastRay = 0.001f;
|
||||||
protected DetailLevel m_primLodInCastRay = DetailLevel.Medium;
|
protected DetailLevel m_primLodInCastRay = DetailLevel.Medium;
|
||||||
protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium;
|
protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium;
|
||||||
protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest;
|
protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest;
|
||||||
|
@ -241,6 +241,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
protected int m_msMinInCastRay = 2;
|
protected int m_msMinInCastRay = 2;
|
||||||
protected int m_msMaxInCastRay = 40;
|
protected int m_msMaxInCastRay = 40;
|
||||||
protected static List<CastRayCall> m_castRayCalls = new List<CastRayCall>();
|
protected static List<CastRayCall> m_castRayCalls = new List<CastRayCall>();
|
||||||
|
protected bool m_useMeshCacheInCastRay = true;
|
||||||
|
protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>();
|
||||||
|
|
||||||
//An array of HTTP/1.1 headers that are not allowed to be used
|
//An array of HTTP/1.1 headers that are not allowed to be used
|
||||||
//as custom headers by llHTTPRequest.
|
//as custom headers by llHTTPRequest.
|
||||||
|
@ -365,6 +367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay);
|
m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay);
|
||||||
m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay);
|
m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay);
|
||||||
m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay);
|
m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay);
|
||||||
|
m_useMeshCacheInCastRay = lslConfig.GetBoolean("UseMeshCacheInLlCastRay", m_useMeshCacheInCastRay);
|
||||||
}
|
}
|
||||||
|
|
||||||
IConfig smtpConfig = seConfigSource.Configs["SMTP"];
|
IConfig smtpConfig = seConfigSource.Configs["SMTP"];
|
||||||
|
@ -14240,50 +14243,85 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
rayTrans.Position1RayProj = pos1RayProj;
|
rayTrans.Position1RayProj = pos1RayProj;
|
||||||
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
|
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
|
||||||
|
|
||||||
// Make an OMV prim to be able to mesh part
|
// Get detail level depending on type
|
||||||
Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart);
|
int lod = 0;
|
||||||
byte[] sculptAsset = null;
|
// Mesh detail level
|
||||||
if (omvPrim.Sculpt != null)
|
if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
|
||||||
sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
|
lod = (int)m_meshLodInCastRay;
|
||||||
FacetedMesh mesh = null;
|
// Sculpt detail level
|
||||||
|
else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
|
||||||
|
lod = (int)m_sculptLodInCastRay;
|
||||||
|
// Shape detail level
|
||||||
|
else if (!part.Shape.SculptEntry)
|
||||||
|
lod = (int)m_primLodInCastRay;
|
||||||
|
|
||||||
// When part is mesh, get mesh and check for hits
|
// Try to get cached mesh if configured
|
||||||
if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
|
ulong meshKey = 0;
|
||||||
|
FacetedMesh mesh = null;
|
||||||
|
if (m_useMeshCacheInCastRay)
|
||||||
{
|
{
|
||||||
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
|
meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod));
|
||||||
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh);
|
lock (m_cachedMeshes)
|
||||||
meshAsset = null;
|
{
|
||||||
|
m_cachedMeshes.TryGetValue(meshKey, out mesh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When part is sculpt, create mesh and check for hits
|
// Create mesh if no cached mesh
|
||||||
// Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt.
|
if (mesh == null)
|
||||||
else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
|
|
||||||
{
|
{
|
||||||
IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
|
// Make an OMV prim to be able to mesh part
|
||||||
if (imgDecoder != null)
|
Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart);
|
||||||
|
byte[] sculptAsset = null;
|
||||||
|
if (omvPrim.Sculpt != null)
|
||||||
|
sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
|
||||||
|
|
||||||
|
// When part is mesh, get mesh
|
||||||
|
if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
|
||||||
{
|
{
|
||||||
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
|
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
|
||||||
if (sculpt != null)
|
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh);
|
||||||
|
meshAsset = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When part is sculpt, create mesh
|
||||||
|
// Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt.
|
||||||
|
else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
|
||||||
|
{
|
||||||
|
IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
|
||||||
|
if (imgDecoder != null)
|
||||||
{
|
{
|
||||||
mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
|
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
|
||||||
sculpt.Dispose();
|
if (sculpt != null)
|
||||||
|
{
|
||||||
|
mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
|
||||||
|
sculpt.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When part is shape, create mesh
|
||||||
|
else if (omvPrim.Sculpt == null)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 &&
|
||||||
|
omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 &&
|
||||||
|
omvPrim.PrimData.PathSkew == 0.0 &&
|
||||||
|
omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
|
||||||
|
)
|
||||||
|
rayTrans.ShapeNeedsEnds = false;
|
||||||
|
mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache mesh if configured
|
||||||
|
if (m_useMeshCacheInCastRay && mesh != null)
|
||||||
|
{
|
||||||
|
lock(m_cachedMeshes)
|
||||||
|
{
|
||||||
|
m_cachedMeshes.Add(meshKey, mesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// When part is prim, create mesh and check for hits
|
|
||||||
else if (omvPrim.Sculpt == null)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 &&
|
|
||||||
omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 &&
|
|
||||||
omvPrim.PrimData.PathSkew == 0.0 &&
|
|
||||||
omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
|
|
||||||
)
|
|
||||||
rayTrans.ShapeNeedsEnds = false;
|
|
||||||
mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check mesh for ray hits
|
// Check mesh for ray hits
|
||||||
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
||||||
mesh = null;
|
mesh = null;
|
||||||
|
@ -14331,11 +14369,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
rayTrans.Position1RayProj = pos1RayProj;
|
rayTrans.Position1RayProj = pos1RayProj;
|
||||||
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
|
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
|
||||||
|
|
||||||
// Make OMV prim, create and check mesh
|
// Try to get cached mesh if configured
|
||||||
PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere();
|
PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere();
|
||||||
prim.Scale = scalePart;
|
int lod = (int)m_avatarLodInCastRay;
|
||||||
Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart);
|
ulong meshKey = prim.GetMeshKey(Vector3.One, (float)(4 << lod));
|
||||||
FacetedMesh mesh = primMesher.GenerateFacetedMesh(omvPrim, m_meshLodInCastRay);
|
FacetedMesh mesh = null;
|
||||||
|
if (m_useMeshCacheInCastRay)
|
||||||
|
{
|
||||||
|
lock (m_cachedMeshes)
|
||||||
|
{
|
||||||
|
m_cachedMeshes.TryGetValue(meshKey, out mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create mesh if no cached mesh
|
||||||
|
if (mesh == null)
|
||||||
|
{
|
||||||
|
// Make OMV prim and create mesh
|
||||||
|
prim.Scale = scalePart;
|
||||||
|
Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart);
|
||||||
|
mesh = primMesher.GenerateFacetedMesh(omvPrim, m_avatarLodInCastRay);
|
||||||
|
|
||||||
|
// Cache mesh if configured
|
||||||
|
if (m_useMeshCacheInCastRay && mesh != null)
|
||||||
|
{
|
||||||
|
lock(m_cachedMeshes)
|
||||||
|
{
|
||||||
|
m_cachedMeshes.Add(meshKey, mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check mesh for ray hits
|
||||||
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
||||||
mesh = null;
|
mesh = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1496,10 +1496,10 @@
|
||||||
UseLlCastRayV3 = false
|
UseLlCastRayV3 = false
|
||||||
|
|
||||||
; Accepted calculation precision error in calculations in llCastRay V3
|
; Accepted calculation precision error in calculations in llCastRay V3
|
||||||
FloatToleranceInLlCastRay = 0.000001
|
FloatToleranceInLlCastRay = 0.00001
|
||||||
|
|
||||||
; Accepted distance difference between duplicate hits in llCastRay V3
|
; Accepted distance difference between duplicate hits in llCastRay V3
|
||||||
FloatTolerance2InLlCastRay = 0.0001
|
FloatTolerance2InLlCastRay = 0.001
|
||||||
|
|
||||||
; Detail level when rendering prims in llCastRay V3
|
; Detail level when rendering prims in llCastRay V3
|
||||||
; 0 = Low, 1 = Medium, 2 = High, 3 = Highest, higer level gives better accuracy but slower call
|
; 0 = Low, 1 = Medium, 2 = High, 3 = Highest, higer level gives better accuracy but slower call
|
||||||
|
@ -1551,6 +1551,10 @@
|
||||||
; Maximum available time in ms possible in llCastRay V3, not to get too high values with varregions
|
; Maximum available time in ms possible in llCastRay V3, not to get too high values with varregions
|
||||||
MaximumAvailableTimeInMsInLlCastRay = 40
|
MaximumAvailableTimeInMsInLlCastRay = 40
|
||||||
|
|
||||||
|
; Use cached meshes in llCastRay V3 if true
|
||||||
|
; Improves performance but uses more memory
|
||||||
|
UseMeshCacheInLlCastRay = true
|
||||||
|
|
||||||
|
|
||||||
[DataSnapshot]
|
[DataSnapshot]
|
||||||
; The following set of configs pertains to search.
|
; The following set of configs pertains to search.
|
||||||
|
|
Loading…
Reference in New Issue