From 128c72a23437423d87cc9b10815f96d7362bddd1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 25 Mar 2013 21:24:21 +0000
Subject: Start recording inter-region teleport attempts, aborts, cancels and
failures in statistics for monitoring/debugging purposes
These are recorded as 'entitytransfer' stats as seen by the "show stats entitytransfer" console command.
---
.../EntityTransfer/EntityTransferModule.cs | 119 +++++++++++++++++++--
1 file changed, 109 insertions(+), 10 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 136caad..4cf7645 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -33,6 +33,7 @@ using System.Threading;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Client;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Physics.Manager;
@@ -77,6 +78,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
public bool DisableInterRegionTeleportCancellation { get; set; }
+ ///
+ /// Number of times inter-region teleport was attempted.
+ ///
+ private Stat m_interRegionTeleportAttempts;
+
+ ///
+ /// Number of times inter-region teleport was aborted (due to simultaneous client logout).
+ ///
+ private Stat m_interRegionTeleportAborts;
+
+ ///
+ /// Number of times inter-region teleport was successfully cancelled by the client.
+ ///
+ private Stat m_interRegionTeleportCancels;
+
+ ///
+ /// Number of times inter-region teleport failed due to server/client/network problems (e.g. viewer failed to
+ /// connect with destination region).
+ ///
+ ///
+ /// This is not necessarily a problem for this simulator - in open-grid/hg conditions, viewer connectivity to
+ /// destination simulator is unknown.
+ ///
+ private Stat m_interRegionTeleportFailures;
+
protected bool m_Enabled = false;
public Scene Scene { get; private set; }
@@ -156,6 +182,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Scene = scene;
+ m_interRegionTeleportAttempts =
+ new Stat(
+ "InterRegionTeleportAttempts",
+ "Number of inter-region teleports attempted.",
+ "This does not count attempts which failed due to pre-conditions (e.g. target simulator refused access).\n"
+ + "You can get successfully teleports by subtracting aborts, cancels and teleport failures from this figure.",
+ "",
+ "entitytransfer",
+ Scene.Name,
+ StatType.Push,
+ null,
+ StatVerbosity.Debug);
+
+ m_interRegionTeleportAborts =
+ new Stat(
+ "InterRegionTeleportAborts",
+ "Number of inter-region teleports aborted due to client actions.",
+ "The chief action is simultaneous logout whilst teleporting.",
+ "",
+ "entitytransfer",
+ Scene.Name,
+ StatType.Push,
+ null,
+ StatVerbosity.Debug);
+
+ m_interRegionTeleportCancels =
+ new Stat(
+ "InterRegionTeleportCancels",
+ "Number of inter-region teleports cancelled by the client.",
+ null,
+ "",
+ "entitytransfer",
+ Scene.Name,
+ StatType.Push,
+ null,
+ StatVerbosity.Debug);
+
+ m_interRegionTeleportFailures =
+ new Stat(
+ "InterRegionTeleportFailures",
+ "Number of inter-region teleports that failed due to server/client/network issues.",
+ "This number may not be very helpful in open-grid/hg situations as the network connectivity/quality of destinations is uncontrollable.",
+ "",
+ "entitytransfer",
+ Scene.Name,
+ StatType.Push,
+ null,
+ StatVerbosity.Debug);
+
+ StatsManager.RegisterStat(m_interRegionTeleportAttempts);
+ StatsManager.RegisterStat(m_interRegionTeleportAborts);
+ StatsManager.RegisterStat(m_interRegionTeleportCancels);
+ StatsManager.RegisterStat(m_interRegionTeleportFailures);
+
scene.RegisterModuleInterface(this);
scene.EventManager.OnNewClient += OnNewClient;
}
@@ -173,7 +253,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public virtual void Close() {}
- public virtual void RemoveRegion(Scene scene) {}
+ public virtual void RemoveRegion(Scene scene)
+ {
+ StatsManager.DeregisterStat(m_interRegionTeleportAttempts);
+ StatsManager.DeregisterStat(m_interRegionTeleportAborts);
+ StatsManager.DeregisterStat(m_interRegionTeleportCancels);
+ StatsManager.DeregisterStat(m_interRegionTeleportFailures);
+ }
public virtual void RegionLoaded(Scene scene)
{
@@ -545,6 +631,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
+ // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target
+ // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these
+ // as server attempts.
+ m_interRegionTeleportAttempts.Value++;
+
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
// Fixing a bug where teleporting while sitting results in the avatar ending up removed from
@@ -595,6 +686,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
bool logout = false;
if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
{
+ m_interRegionTeleportFailures.Value++;
+
sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
m_log.DebugFormat(
@@ -606,6 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
{
+ m_interRegionTeleportCancels.Value++;
+
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
@@ -614,6 +709,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
+ m_interRegionTeleportAborts.Value++;
+
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
@@ -683,6 +780,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// establish th econnection to the destination which makes it return true.
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
+ m_interRegionTeleportAborts.Value++;
+
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
@@ -698,6 +797,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
+ m_interRegionTeleportAborts.Value++;
+
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
@@ -715,6 +816,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
{
+ m_interRegionTeleportCancels.Value++;
+
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
@@ -750,6 +853,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
+ m_interRegionTeleportAborts.Value++;
+
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
@@ -762,6 +867,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion.");
+
return;
}
@@ -803,15 +909,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// now we have a child agent in this region.
sp.Reset();
}
-
- // Commented pending deletion since this method no longer appears to do anything at all
-// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
-// if (sp.Scene.NeedSceneCacheClear(sp.UUID))
-// {
-// m_log.DebugFormat(
-// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
-// sp.UUID);
-// }
}
///
@@ -847,6 +944,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
CleanupFailedInterRegionTeleport(sp, finalDestination);
+ m_interRegionTeleportFailures.Value++;
+
sp.ControllingClient.SendTeleportFailed(
string.Format(
"Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason));
--
cgit v1.1
From f783b9169fbc0544ec6c634900cb34bf48c6b2a9 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Fri, 22 Mar 2013 16:50:56 -0700
Subject: BulletSim: parameterize C# HACD hull creation. Add feature of
reducing max hull count for simple (non-cut prims) meshes.
---
OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 33 +++++++++++++
.../Physics/BulletSPlugin/BSShapeCollection.cs | 55 ++++++++++++++++------
2 files changed, 74 insertions(+), 14 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 4d89a88..26d2d60 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -142,6 +142,14 @@ public static class BSParam
public static float VehicleAngularBankingTimescaleFudge { get; private set; }
public static bool VehicleDebuggingEnabled { get; private set; }
+ // Convex Hulls
+ public static int CSHullMaxDepthSplit { get; private set; }
+ public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; }
+ public static float CSHullConcavityThresholdPercent { get; private set; }
+ public static float CSHullVolumeConservationThresholdPercent { get; private set; }
+ public static int CSHullMaxVertices { get; private set; }
+ public static float CSHullMaxSkinWidth { get; private set; }
+
// Linkset implementation parameters
public static float LinksetImplementation { get; private set; }
public static bool LinkConstraintUseFrameOffset { get; private set; }
@@ -623,6 +631,31 @@ public static class BSParam
(s) => { return GlobalContactBreakingThreshold; },
(s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ),
+ new ParameterDefn("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy",
+ 7,
+ (s) => { return CSHullMaxDepthSplit; },
+ (s,v) => { CSHullMaxDepthSplit = v; } ),
+ new ParameterDefn("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes",
+ 2,
+ (s) => { return CSHullMaxDepthSplitForSimpleShapes; },
+ (s,v) => { CSHullMaxDepthSplitForSimpleShapes = v; } ),
+ new ParameterDefn("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)",
+ 5f,
+ (s) => { return CSHullConcavityThresholdPercent; },
+ (s,v) => { CSHullConcavityThresholdPercent = v; } ),
+ new ParameterDefn("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)",
+ 5f,
+ (s) => { return CSHullVolumeConservationThresholdPercent; },
+ (s,v) => { CSHullVolumeConservationThresholdPercent = v; } ),
+ new ParameterDefn("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.",
+ 32,
+ (s) => { return CSHullMaxVertices; },
+ (s,v) => { CSHullMaxVertices = v; } ),
+ new ParameterDefn("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
+ 0,
+ (s) => { return CSHullMaxSkinWidth; },
+ (s,v) => { CSHullMaxSkinWidth = v; } ),
+
new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
(float)BSLinkset.LinksetImplementation.Compound,
(s) => { return LinksetImplementation; },
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index b16bc10..457f204 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -447,17 +447,10 @@ public sealed class BSShapeCollection : IDisposable
// If the prim attributes are simple, this could be a simple Bullet native shape
if (!haveShape
+ && nativeShapePossible
&& pbs != null
&& !pbs.SculptEntry
- && nativeShapePossible
- && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim)
- || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
- && pbs.ProfileHollow == 0
- && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
- && pbs.PathBegin == 0 && pbs.PathEnd == 0
- && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
- && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
- && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) )
+ && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || PrimHasNoCuts(pbs)) )
{
// Get the scale of any existing shape so we can see if the new shape is same native type and same size.
OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero;
@@ -508,6 +501,18 @@ public sealed class BSShapeCollection : IDisposable
return ret;
}
+ // return 'true' if this shape description does not include any cutting or twisting.
+ private bool PrimHasNoCuts(PrimitiveBaseShape pbs)
+ {
+ return pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
+ && pbs.ProfileHollow == 0
+ && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
+ && pbs.PathBegin == 0 && pbs.PathEnd == 0
+ && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
+ && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
+ && pbs.PathShearX == 0 && pbs.PathShearY == 0;
+ }
+
// return 'true' if the prim's shape was changed.
public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
@@ -518,7 +523,7 @@ public sealed class BSShapeCollection : IDisposable
if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
{
// Update prim.BSShape to reference a hull of this shape.
- ret = GetReferenceToHull(prim,shapeCallback);
+ ret = GetReferenceToHull(prim, shapeCallback);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
}
@@ -697,6 +702,7 @@ public sealed class BSShapeCollection : IDisposable
// See that hull shape exists in the physical world and update prim.BSShape.
// We could be creating the hull because scale changed or whatever.
+ // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance.
private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
BulletShape newShape;
@@ -715,6 +721,7 @@ public sealed class BSShapeCollection : IDisposable
DereferenceShape(prim.PhysShape, shapeCallback);
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
+ // It might not have been created if we're waiting for an asset.
newShape = VerifyMeshCreated(newShape, prim);
ReferenceShape(newShape);
@@ -733,14 +740,14 @@ public sealed class BSShapeCollection : IDisposable
HullDesc hullDesc;
if (Hulls.TryGetValue(newHullKey, out hullDesc))
{
- // If the hull shape already is created, just use it.
+ // If the hull shape already has been created, just use the one shared instance.
newShape = hullDesc.shape.Clone();
}
else
{
- // Build a new hull in the physical world
- // Pass true for physicalness as this creates some sort of bounding box which we don't need
- IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false);
+ // Build a new hull in the physical world.
+ // Pass true for physicalness as this prevents the creation of bounding box which is not needed
+ IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
if (meshData != null)
{
@@ -759,15 +766,35 @@ public sealed class BSShapeCollection : IDisposable
convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
}
+ uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
+ if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
+ {
+ // Simple primitive shapes we know are convex so they are better implemented with
+ // fewer hulls.
+ // Check for simple shape (prim without cuts) and reduce split parameter if so.
+ if (PrimHasNoCuts(pbs))
+ {
+ maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
+ }
+ }
+
// setup and do convex hull conversion
m_hulls = new List();
DecompDesc dcomp = new DecompDesc();
dcomp.mIndices = convIndices;
dcomp.mVertices = convVertices;
+ dcomp.mDepth = maxDepthSplit;
+ dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
+ dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
+ dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
+ dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
// create the hull into the _hulls variable
convexBuilder.process(dcomp);
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
+ BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
+
// Convert the vertices and indices for passing to unmanaged.
// The hull information is passed as a large floating point array.
// The format is:
--
cgit v1.1
From 953090fd62c2f8647d0e04bc3890a04a7076dbad Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Sat, 23 Mar 2013 11:00:52 -0700
Subject: BulletSim: fix possible race condition where an prim's asset can be
requested quicker than the asset fetcher returns and thus falsely reporting
that an asset was not fetched and defaulting the assset to a bounding box.
---
.../Region/Physics/BulletSPlugin/BSPhysObject.cs | 12 ++++++++----
OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +-
.../Physics/BulletSPlugin/BSShapeCollection.cs | 21 +++++++++++++++------
3 files changed, 24 insertions(+), 11 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index f953c1e..6bb88c7 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -86,7 +86,7 @@ public abstract class BSPhysObject : PhysicsActor
PhysBody = new BulletBody(localID);
PhysShape = new BulletShape();
- LastAssetBuildFailed = false;
+ PrimAssetState = PrimAssetCondition.Unknown;
// Default material type. Also sets Friction, Restitution and Density.
SetMaterial((int)MaterialAttributes.Material.Wood);
@@ -133,9 +133,13 @@ public abstract class BSPhysObject : PhysicsActor
// Reference to the physical shape (btCollisionShape) of this object
public BulletShape PhysShape;
- // 'true' if the mesh's underlying asset failed to build.
- // This will keep us from looping after the first time the build failed.
- public bool LastAssetBuildFailed { get; set; }
+ // The physical representation of the prim might require an asset fetch.
+ // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'.
+ public enum PrimAssetCondition
+ {
+ Unknown, Waiting, Failed, Fetched
+ }
+ public PrimAssetCondition PrimAssetState { get; set; }
// The objects base shape information. Null if not a prim type shape.
public PrimitiveBaseShape BaseShape { get; protected set; }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 2cbbe9a..6a5461a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -155,7 +155,7 @@ public class BSPrim : BSPhysObject
public override PrimitiveBaseShape Shape {
set {
BaseShape = value;
- LastAssetBuildFailed = false;
+ PrimAssetState = PrimAssetCondition.Unknown;
ForceBodyShapeRebuild(false);
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 457f204..a6e20a8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -930,11 +930,15 @@ public sealed class BSShapeCollection : IDisposable
return newShape;
// If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
- if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero)
+ if (prim.BaseShape.SculptEntry
+ && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed
+ && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
+ && prim.BaseShape.SculptTexture != OMV.UUID.Zero
+ )
{
- DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed);
- // This will prevent looping through this code as we keep trying to get the failed shape
- prim.LastAssetBuildFailed = true;
+ DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID);
+ // Multiple requestors will know we're waiting for this asset
+ prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
BSPhysObject xprim = prim;
Util.FireAndForget(delegate
@@ -945,7 +949,7 @@ public sealed class BSShapeCollection : IDisposable
BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
{
- bool assetFound = false; // DEBUG DEBUG
+ bool assetFound = false;
string mismatchIDs = String.Empty; // DEBUG DEBUG
if (asset != null && yprim.BaseShape.SculptEntry)
{
@@ -963,6 +967,10 @@ public sealed class BSShapeCollection : IDisposable
mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
}
}
+ if (assetFound)
+ yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
+ else
+ yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
@@ -970,6 +978,7 @@ public sealed class BSShapeCollection : IDisposable
}
else
{
+ xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
LogHeader, PhysicsScene.Name);
}
@@ -977,7 +986,7 @@ public sealed class BSShapeCollection : IDisposable
}
else
{
- if (prim.LastAssetBuildFailed)
+ if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
{
PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
LogHeader, prim.LocalID, prim.BaseShape.SculptTexture);
--
cgit v1.1
From c96a6f1de6d5e66dd2055365c26144d7a92f2fc5 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Sat, 23 Mar 2013 11:03:59 -0700
Subject: BulletSim: small tweaks and formatting in the parameter fetching
code.
---
OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 26d2d60..f3454c8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -203,10 +203,10 @@ public static class BSParam
public delegate void PSetOnObject(BSScene scene, BSPhysObject obj);
public sealed class ParameterDefn : ParameterDefnBase
{
- T defaultValue;
- PSetValue setter;
- PGetValue getter;
- PSetOnObject objectSet;
+ private T defaultValue;
+ private PSetValue setter;
+ private PGetValue getter;
+ private PSetOnObject objectSet;
public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue pGetter, PSetValue pSetter)
: base(pName, pDesc)
{
@@ -223,13 +223,23 @@ public static class BSParam
getter = pGetter;
objectSet = pObjSetter;
}
+ /* Wish I could simplify using this definition but CLR doesn't store references so closure around delegates of references won't work
+ public ParameterDefn(string pName, string pDesc, T pDefault, ref T loc)
+ : base(pName, pDesc)
+ {
+ defaultValue = pDefault;
+ setter = (s, v) => { loc = v; };
+ getter = (s) => { return loc; };
+ objectSet = null;
+ }
+ */
public override void AssignDefault(BSScene s)
{
setter(s, defaultValue);
}
public override string GetValue(BSScene s)
{
- return String.Format("{0}", getter(s));
+ return getter(s).ToString();
}
public override void SetValue(BSScene s, string valAsString)
{
@@ -252,6 +262,7 @@ public static class BSParam
try
{
T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString });
+ // Store the parsed value
setter(s, setValue);
// s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue);
}
--
cgit v1.1
From 285dc554ece0b504cb549193096f84c9c0cfe89f Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Mon, 25 Mar 2013 15:19:55 -0700
Subject: BulletSim: new algorithm for vertical attraction which uses
quaternion arithmetic to compute the shortest path between the current tilt
and vertical.
---
OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 48 ++++++++++++++++++++--
1 file changed, 45 insertions(+), 3 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 5549984..65df741 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -321,7 +321,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
}
}
- internal void ProcessTypeChange(Vehicle pType)
+ public void ProcessTypeChange(Vehicle pType)
{
VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType);
// Set Defaults For Type
@@ -1301,14 +1301,52 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay.
public void ComputeAngularVerticalAttraction()
{
+
// If vertical attaction timescale is reasonable
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{
+ // Possible solution derived from a discussion at:
+ // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
+
+ // Create a rotation that is only the vehicle's rotation around Z
+ Vector3 currentEuler = Vector3.Zero;
+ VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
+ Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
+
+ // Create the axis that is perpendicular to the up vector and the rotated up vector.
+ Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
+ // Compute the angle between those to vectors.
+ double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
+ // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
+
+ // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
+ // TODO: add 'efficiency'.
+ differenceAngle /= m_verticalAttractionTimescale;
+
+ // Create the quaterian representing the correction angle
+ Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
+
+ // Turn that quaternion into Euler values to make it into velocities to apply.
+ Vector3 vertContributionV = Vector3.Zero;
+ correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
+ vertContributionV *= -1f;
+
+ VehicleRotationalVelocity += vertContributionV;
+
+ VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
+ Prim.LocalID,
+ differenceAxis,
+ differenceAngle,
+ correctionRotation,
+ vertContributionV);
+
+ // ===================================================================
+ /*
Vector3 vertContributionV = Vector3.Zero;
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
// Take a vector pointing up and convert it from world to vehicle relative coords.
- Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
+ Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
// If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
// is now:
@@ -1334,13 +1372,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
// Correction happens over a number of seconds.
Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
+
+ // The correction happens over the user's time period
vertContributionV /= m_verticalAttractionTimescale;
- VehicleRotationalVelocity += vertContributionV;
+ // Rotate the vehicle rotation to the world coordinates.
+ VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
+ */
}
}
--
cgit v1.1