xlIDs = lIDs;
@@ -1326,11 +1462,21 @@ public class BSScene : PhysicsScene, IPhysicsParameters
#endregion Runtime settable parameters
+ // Debugging routine for dumping detailed physical information for vehicle prims
+ private void DumpVehicles()
+ {
+ foreach (BSPrim prim in m_vehicles)
+ {
+ BulletSimAPI.DumpRigidBody2(World.ptr, prim.PhysBody.ptr);
+ BulletSimAPI.DumpCollisionShape2(World.ptr, prim.PhysShape.ptr);
+ }
+ }
+
// Invoke the detailed logger and output something if it's enabled.
public void DetailLog(string msg, params Object[] args)
{
PhysicsLogging.Write(msg, args);
- // Add the Flush() if debugging crashes to get all the messages written out.
+ // Add the Flush() if debugging crashes. Gets all the messages written out.
// PhysicsLogging.Flush();
}
// Used to fill in the LocalID when there isn't one. It's the correct number of characters.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 30fa50a6fd..29a23c0247 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -34,11 +34,11 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
namespace OpenSim.Region.Physics.BulletSPlugin
{
-public class BSShapeCollection : IDisposable
+public sealed class BSShapeCollection : IDisposable
{
private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]";
- protected BSScene PhysicsScene { get; set; }
+ private BSScene PhysicsScene { get; set; }
private Object m_collectionActivityLock = new Object();
@@ -48,6 +48,7 @@ public class BSShapeCollection : IDisposable
public IntPtr ptr;
public int referenceCount;
public DateTime lastReferenced;
+ public UInt64 shapeKey;
}
// Description of a hull.
@@ -57,6 +58,7 @@ public class BSShapeCollection : IDisposable
public IntPtr ptr;
public int referenceCount;
public DateTime lastReferenced;
+ public UInt64 shapeKey;
}
// The sharable set of meshes and hulls. Indexed by their shape hash.
@@ -90,9 +92,10 @@ public class BSShapeCollection : IDisposable
// remove the physical constraints before the body is destroyed.
// Called at taint-time!!
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim,
- ShapeData shapeData, PrimitiveBaseShape pbs,
ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
{
+ PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape");
+
bool ret = false;
// This lock could probably be pushed down lower but building shouldn't take long
@@ -100,41 +103,38 @@ public class BSShapeCollection : IDisposable
{
// Do we have the correct geometry for this type of object?
// Updates prim.BSShape with information/pointers to shape.
- // CreateGeom returns 'true' of BSShape as changed to a new shape.
- bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback);
+ // Returns 'true' of BSShape is changed to a new shape.
+ bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback);
// If we had to select a new shape geometry for the object,
// rebuild the body around it.
// Updates prim.BSBody with information/pointers to requested body
+ // Returns 'true' if BSBody was changed.
bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World,
- prim.BSShape, shapeData, bodyCallback);
+ prim.PhysShape, bodyCallback);
ret = newGeom || newBody;
}
- DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}",
- prim.LocalID, forceRebuild, ret, prim.BSBody, prim.BSShape);
+ DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}",
+ prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape);
return ret;
}
- // Track another user of a body
+ // Track another user of a body.
// We presume the caller has allocated the body.
// Bodies only have one user so the body is just put into the world if not already there.
public void ReferenceBody(BulletBody body, bool inTaintTime)
{
lock (m_collectionActivityLock)
{
- DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body);
- BSScene.TaintCallback createOperation = delegate()
+ DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
+ PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate()
{
if (!BulletSimAPI.IsInWorld2(body.ptr))
{
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
}
- };
- if (inTaintTime)
- createOperation();
- else
- PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
+ });
}
}
@@ -147,25 +147,23 @@ public class BSShapeCollection : IDisposable
lock (m_collectionActivityLock)
{
- BSScene.TaintCallback removeOperation = delegate()
+ PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate()
{
- DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}",
- body.ID, body.ptr.ToString("X"), inTaintTime);
+ DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}",
+ body.ID, body, inTaintTime);
// If the caller needs to know the old body is going away, pass the event up.
if (bodyCallback != null) bodyCallback(body);
- // It may have already been removed from the world in which case the next is a NOOP.
- BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
+ if (BulletSimAPI.IsInWorld2(body.ptr))
+ {
+ BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
+ DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
+ }
// Zero any reference to the shape so it is not freed when the body is deleted.
BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
- };
- // If already in taint-time, do the operations now. Otherwise queue for later.
- if (inTaintTime)
- removeOperation();
- else
- PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation);
+ });
}
}
@@ -175,7 +173,7 @@ public class BSShapeCollection : IDisposable
// Meshes and hulls for the same shape have the same hash key.
// NOTE that native shapes are not added to the mesh list or removed.
// Returns 'true' if this is the initial reference to the shape. Otherwise reused.
- private bool ReferenceShape(BulletShape shape)
+ public bool ReferenceShape(BulletShape shape)
{
bool ret = false;
switch (shape.type)
@@ -193,6 +191,7 @@ public class BSShapeCollection : IDisposable
{
// This is a new reference to a mesh
meshDesc.ptr = shape.ptr;
+ meshDesc.shapeKey = shape.shapeKey;
// We keep a reference to the underlying IMesh data so a hull can be built
meshDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}",
@@ -215,6 +214,7 @@ public class BSShapeCollection : IDisposable
{
// This is a new reference to a hull
hullDesc.ptr = shape.ptr;
+ hullDesc.shapeKey = shape.shapeKey;
hullDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
@@ -239,7 +239,7 @@ public class BSShapeCollection : IDisposable
if (shape.ptr == IntPtr.Zero)
return;
- BSScene.TaintCallback dereferenceOperation = delegate()
+ PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate()
{
if (shape.ptr != IntPtr.Zero)
{
@@ -261,6 +261,9 @@ public class BSShapeCollection : IDisposable
case ShapeData.PhysicsShapeType.SHAPE_MESH:
DereferenceMesh(shape, shapeCallback);
break;
+ case ShapeData.PhysicsShapeType.SHAPE_COMPOUND:
+ DereferenceCompound(shape, shapeCallback);
+ break;
case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN:
break;
default:
@@ -268,18 +271,7 @@ public class BSShapeCollection : IDisposable
}
}
}
- };
- if (inTaintTime)
- {
- lock (m_collectionActivityLock)
- {
- dereferenceOperation();
- }
- }
- else
- {
- PhysicsScene.TaintedObject("BSShapeCollection.DereferenceShape", dereferenceOperation);
- }
+ });
}
// Count down the reference count for a mesh shape
@@ -294,8 +286,8 @@ public class BSShapeCollection : IDisposable
if (shapeCallback != null) shapeCallback(shape);
meshDesc.lastReferenced = System.DateTime.Now;
Meshes[shape.shapeKey] = meshDesc;
- DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}",
- BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
+ DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}",
+ BSScene.DetailLogZero, shape, meshDesc.referenceCount);
}
}
@@ -309,11 +301,94 @@ public class BSShapeCollection : IDisposable
{
hullDesc.referenceCount--;
// TODO: release the Bullet storage (aging old entries?)
+
+ // Tell upper layers that, if they have dependencies on this shape, this link is going away
if (shapeCallback != null) shapeCallback(shape);
+
hullDesc.lastReferenced = System.DateTime.Now;
Hulls[shape.shapeKey] = hullDesc;
- DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}",
- BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
+ DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}",
+ BSScene.DetailLogZero, shape, hullDesc.referenceCount);
+ }
+ }
+
+ // Remove a reference to a compound shape.
+ // Taking a compound shape apart is a little tricky because if you just delete the
+ // physical shape, it will free all the underlying children. We can't do that because
+ // they could be shared. So, this removes each of the children from the compound and
+ // dereferences them separately before destroying the compound collision object itself.
+ // Called at taint-time.
+ private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback)
+ {
+ if (!BulletSimAPI.IsCompound2(shape.ptr))
+ {
+ // Failed the sanity check!!
+ PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
+ LogHeader, shape.type, shape.ptr.ToString("X"));
+ DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
+ BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X"));
+ return;
+ }
+
+ int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr);
+ DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
+
+ for (int ii = numChildren - 1; ii >= 0; ii--)
+ {
+ IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii);
+ DereferenceAnonCollisionShape(childShape);
+ }
+ BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
+ }
+
+ // Sometimes we have a pointer to a collision shape but don't know what type it is.
+ // Figure out type and call the correct dereference routine.
+ // Called at taint-time.
+ private void DereferenceAnonCollisionShape(IntPtr cShape)
+ {
+ MeshDesc meshDesc;
+ HullDesc hullDesc;
+
+ BulletShape shapeInfo = new BulletShape(cShape);
+ if (TryGetMeshByPtr(cShape, out meshDesc))
+ {
+ shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_MESH;
+ shapeInfo.shapeKey = meshDesc.shapeKey;
+ }
+ else
+ {
+ if (TryGetHullByPtr(cShape, out hullDesc))
+ {
+ shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_HULL;
+ shapeInfo.shapeKey = hullDesc.shapeKey;
+ }
+ else
+ {
+ if (BulletSimAPI.IsCompound2(cShape))
+ {
+ shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND;
+ }
+ else
+ {
+ if (BulletSimAPI.IsNativeShape2(cShape))
+ {
+ shapeInfo.isNativeShape = true;
+ shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
+ }
+ }
+ }
+ }
+
+ DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo);
+
+ if (shapeInfo.type != ShapeData.PhysicsShapeType.SHAPE_UNKNOWN)
+ {
+ DereferenceShape(shapeInfo, true, null);
+ }
+ else
+ {
+ PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}",
+ LogHeader, PhysicsScene.RegionName, cShape.ToString("X"));
}
}
@@ -325,22 +400,46 @@ public class BSShapeCollection : IDisposable
// Info in prim.BSShape is updated to the new shape.
// Returns 'true' if the geometry was rebuilt.
// Called at taint-time!
- private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeData shapeData,
- PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback)
+ private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
+ {
+ bool ret = false;
+ bool haveShape = false;
+
+ if (!haveShape && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
+ {
+ // an avatar capsule is close to a native shape (it is not shared)
+ ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
+ ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback);
+ DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
+ ret = true;
+ haveShape = true;
+ }
+
+ // Compound shapes are handled special as they are rebuilt from scratch.
+ // This isn't too great a hardship since most of the child shapes will already been created.
+ if (!haveShape && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND)
+ {
+ ret = GetReferenceToCompoundShape(prim, shapeCallback);
+ DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape);
+ haveShape = true;
+ }
+
+ if (!haveShape)
+ {
+ ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback);
+ }
+
+ return ret;
+ }
+
+ // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'.
+ private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
bool ret = false;
bool haveShape = false;
bool nativeShapePossible = true;
+ PrimitiveBaseShape pbs = prim.BaseShape;
- if (shapeData.Type == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
- {
- // an avatar capsule is close to a native shape (it is not shared)
- ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
- ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback);
- DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.BSShape);
- ret = true;
- haveShape = true;
- }
// If the prim attributes are simple, this could be a simple Bullet native shape
if (!haveShape
&& pbs != null
@@ -354,98 +453,110 @@ public class BSShapeCollection : IDisposable
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
&& pbs.PathShearX == 0 && pbs.PathShearY == 0) ) )
{
+ // It doesn't look like Bullet scales spheres so make sure the scales are all equal
if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)
{
haveShape = true;
if (forceRebuild
- || prim.Scale != shapeData.Size
- || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
+ || prim.Scale != prim.Size
+ || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
)
{
- ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
+ ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
- prim.LocalID, forceRebuild, prim.BSShape);
+ prim.LocalID, forceRebuild, prim.PhysShape);
}
}
- if (pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
+ if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
{
haveShape = true;
if (forceRebuild
- || prim.Scale != shapeData.Size
- || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
+ || prim.Scale != prim.Size
+ || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
)
{
- ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX,
+ ret = GetReferenceToNativeShape( prim, ShapeData.PhysicsShapeType.SHAPE_BOX,
ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
- prim.LocalID, forceRebuild, prim.BSShape);
+ prim.LocalID, forceRebuild, prim.PhysShape);
}
}
}
+
// If a simple shape is not happening, create a mesh and possibly a hull.
- // Note that if it's a native shape, the check for physical/non-physical is not
- // made. Native shapes are best used in either case.
if (!haveShape && pbs != null)
{
- if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects)
- {
- // Update prim.BSShape to reference a hull of this shape.
- ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback);
- DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
- shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
- }
- else
- {
- ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback);
- DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
- shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
- }
+ ret = CreateGeomMeshOrHull(prim, shapeCallback);
+ }
+
+ return ret;
+ }
+
+ public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
+ {
+
+ bool ret = false;
+ // Note that if it's a native shape, the check for physical/non-physical is not
+ // made. Native shapes work in either case.
+ if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects)
+ {
+ // Update prim.BSShape to reference a hull of this shape.
+ ret = GetReferenceToHull(prim,shapeCallback);
+ DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
+ prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
+ }
+ else
+ {
+ ret = GetReferenceToMesh(prim, shapeCallback);
+ DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
+ prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
}
return ret;
}
// Creates a native shape and assignes it to prim.BSShape.
// "Native" shapes are never shared. they are created here and destroyed in DereferenceShape().
- private bool GetReferenceToNativeShape(BSPhysObject prim, ShapeData shapeData,
+ private bool GetReferenceToNativeShape(BSPhysObject prim,
ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
ShapeDestructionCallback shapeCallback)
{
// release any previous shape
- DereferenceShape(prim.BSShape, true, shapeCallback);
+ DereferenceShape(prim.PhysShape, true, shapeCallback);
- shapeData.Type = shapeType;
// Bullet native objects are scaled by the Bullet engine so pass the size in
- prim.Scale = shapeData.Size;
- shapeData.Scale = shapeData.Size;
+ prim.Scale = prim.Size;
- BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey);
+ BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
- shapeData.ID, newShape, shapeData.Scale);
+ prim.LocalID, newShape, prim.Scale);
- prim.BSShape = newShape;
+ prim.PhysShape = newShape;
return true;
}
- private BulletShape BuildPhysicalNativeShape(ShapeData.PhysicsShapeType shapeType,
- ShapeData shapeData, ShapeData.FixedShapeKey shapeKey)
+ private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, ShapeData.PhysicsShapeType shapeType,
+ ShapeData.FixedShapeKey shapeKey)
{
BulletShape newShape;
// Need to make sure the passed shape information is for the native type.
- ShapeData nativeShapeData = shapeData;
+ ShapeData nativeShapeData = new ShapeData();
nativeShapeData.Type = shapeType;
+ nativeShapeData.ID = prim.LocalID;
+ nativeShapeData.Scale = prim.Scale;
+ nativeShapeData.Size = prim.Scale;
nativeShapeData.MeshKey = (ulong)shapeKey;
nativeShapeData.HullKey = (ulong)shapeKey;
if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
{
newShape = new BulletShape(
- BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, nativeShapeData.Scale)
+ BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
, shapeType);
- DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale);
+ DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
}
else
{
@@ -454,7 +565,7 @@ public class BSShapeCollection : IDisposable
if (newShape.ptr == IntPtr.Zero)
{
PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
- LogHeader, nativeShapeData.ID, nativeShapeData.Type);
+ LogHeader, prim.LocalID, shapeType);
}
newShape.shapeKey = (System.UInt64)shapeKey;
newShape.isNativeShape = true;
@@ -466,33 +577,32 @@ public class BSShapeCollection : IDisposable
// Dereferences previous shape in BSShape and adds a reference for this new shape.
// Returns 'true' of a mesh was actually built. Otherwise .
// Called at taint-time!
- private bool GetReferenceToMesh(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs,
- ShapeDestructionCallback shapeCallback)
+ private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
BulletShape newShape = new BulletShape(IntPtr.Zero);
float lod;
- System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod);
+ System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
// if this new shape is the same as last time, don't recreate the mesh
- if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH)
+ if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH)
return false;
- DetailLog("{0},BSShapeCollection.CreateGeomMesh,create,oldKey={1},newKey={2}",
- prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
+ DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}",
+ prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
// Since we're recreating new, get rid of the reference to the previous shape
- DereferenceShape(prim.BSShape, true, shapeCallback);
+ DereferenceShape(prim.PhysShape, true, shapeCallback);
- newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod);
+ newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod);
// Take evasive action if the mesh was not constructed.
- newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs);
+ newShape = VerifyMeshCreated(newShape, prim);
ReferenceShape(newShape);
// meshes are already scaled by the meshmerizer
prim.Scale = new OMV.Vector3(1f, 1f, 1f);
- prim.BSShape = newShape;
+ prim.PhysShape = newShape;
return true; // 'true' means a new shape has been added to this prim
}
@@ -526,7 +636,7 @@ public class BSShapeCollection : IDisposable
verticesAsFloats[vi++] = vv.Z;
}
- // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
+ // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
// LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count);
meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
@@ -541,32 +651,31 @@ public 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.
- private bool GetReferenceToHull(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs,
- ShapeDestructionCallback shapeCallback)
+ private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
BulletShape newShape;
float lod;
- System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod);
+ System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
// if the hull hasn't changed, don't rebuild it
- if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL)
+ if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL)
return false;
- DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}",
- prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
+ DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}",
+ prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
// Remove usage of the previous shape.
- DereferenceShape(prim.BSShape, true, shapeCallback);
+ DereferenceShape(prim.PhysShape, true, shapeCallback);
- newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
- newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs);
+ newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
+ newShape = VerifyMeshCreated(newShape, prim);
ReferenceShape(newShape);
// hulls are already scaled by the meshmerizer
prim.Scale = new OMV.Vector3(1f, 1f, 1f);
- prim.BSShape = newShape;
+ prim.PhysShape = newShape;
return true; // 'true' means a new shape has been added to this prim
}
@@ -685,9 +794,31 @@ public class BSShapeCollection : IDisposable
return;
}
+ // Compound shapes are always built from scratch.
+ // This shouldn't be to bad since most of the parts will be meshes that had been built previously.
+ private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
+ {
+ // Remove reference to the old shape
+ // Don't need to do this as the shape is freed when the new root shape is created below.
+ // DereferenceShape(prim.PhysShape, true, shapeCallback);
+
+ BulletShape cShape = new BulletShape(
+ BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), ShapeData.PhysicsShapeType.SHAPE_COMPOUND);
+
+ // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
+ CreateGeomMeshOrHull(prim, shapeCallback);
+ BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
+ DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
+ prim.LocalID, cShape, prim.PhysShape);
+
+ prim.PhysShape = cShape;
+
+ return true;
+ }
+
// Create a hash of all the shape parameters to be used as a key
// for this particular shape.
- private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod)
+ private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
{
// level of detail based on size and type of the object
float lod = PhysicsScene.MeshLOD;
@@ -695,40 +826,40 @@ public class BSShapeCollection : IDisposable
lod = PhysicsScene.SculptLOD;
// Mega prims usually get more detail because one can interact with shape approximations at this size.
- float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z));
+ float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
if (maxAxis > PhysicsScene.MeshMegaPrimThreshold)
lod = PhysicsScene.MeshMegaPrimLOD;
retLod = lod;
- return pbs.GetMeshKey(shapeData.Size, lod);
+ return pbs.GetMeshKey(size, lod);
}
// For those who don't want the LOD
- private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs)
+ private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs)
{
float lod;
- return ComputeShapeKey(shapeData, pbs, out lod);
+ return ComputeShapeKey(size, pbs, out lod);
}
// The creation of a mesh or hull can fail if an underlying asset is not available.
// There are two cases: 1) the asset is not in the cache and it needs to be fetched;
- // and 2) the asset cannot be converted (like decompressing JPEG2000s).
- // The first case causes the asset to be fetched. The second case just requires
+ // and 2) the asset cannot be converted (like failed decompression of JPEG2000s).
+ // The first case causes the asset to be fetched. The second case requires
// us to not loop forever.
// Called after creating a physical mesh or hull. If the physical shape was created,
// just return.
- private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs)
+ private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim)
{
// If the shape was successfully created, nothing more to do
if (newShape.ptr != IntPtr.Zero)
return newShape;
// If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
- if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero)
+ if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero)
{
prim.LastAssetBuildFailed = true;
BSPhysObject xprim = prim;
DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
- LogHeader, shapeData.ID.ToString("X"), prim.LastAssetBuildFailed);
+ LogHeader, prim.LocalID, prim.LastAssetBuildFailed);
Util.FireAndForget(delegate
{
RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
@@ -745,7 +876,7 @@ public class BSShapeCollection : IDisposable
yprim.BaseShape.SculptData = asset.Data;
// This will cause the prim to see that the filler shape is not the right
// one and try again to build the object.
- // No race condition with the native sphere setting since the rebuild is at taint time.
+ // No race condition with the normal shape setting since the rebuild is at taint time.
yprim.ForceBodyShapeRebuild(false);
});
@@ -757,13 +888,13 @@ public class BSShapeCollection : IDisposable
if (prim.LastAssetBuildFailed)
{
PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
- LogHeader, shapeData.ID, pbs.SculptTexture);
+ LogHeader, prim.LocalID, prim.BaseShape.SculptTexture);
}
}
// While we figure out the real problem, stick a simple native shape on the object.
BulletShape fillinShape =
- BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_BOX, shapeData, ShapeData.FixedShapeKey.KEY_BOX);
+ BuildPhysicalNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX);
return fillinShape;
}
@@ -773,18 +904,18 @@ public class BSShapeCollection : IDisposable
// Returns 'true' if an object was actually created.
// Called at taint-time.
private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape,
- ShapeData shapeData, BodyDestructionCallback bodyCallback)
+ BodyDestructionCallback bodyCallback)
{
bool ret = false;
// the mesh, hull or native shape must have already been created in Bullet
- bool mustRebuild = (prim.BSBody.ptr == IntPtr.Zero);
+ bool mustRebuild = (prim.PhysBody.ptr == IntPtr.Zero);
// If there is an existing body, verify it's of an acceptable type.
// If not a solid object, body is a GhostObject. Otherwise a RigidBody.
if (!mustRebuild)
{
- CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.BSBody.ptr);
+ CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr);
if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY
|| !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT)
{
@@ -796,27 +927,27 @@ public class BSShapeCollection : IDisposable
if (mustRebuild || forceRebuild)
{
// Free any old body
- DereferenceBody(prim.BSBody, true, bodyCallback);
+ DereferenceBody(prim.PhysBody, true, bodyCallback);
BulletBody aBody;
IntPtr bodyPtr = IntPtr.Zero;
if (prim.IsSolid)
{
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
- shapeData.ID, shapeData.Position, shapeData.Rotation);
+ prim.LocalID, prim.RawPosition, prim.RawOrientation);
DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
}
else
{
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
- shapeData.ID, shapeData.Position, shapeData.Rotation);
+ prim.LocalID, prim.ForcePosition, prim.ForceOrientation);
DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
}
- aBody = new BulletBody(shapeData.ID, bodyPtr);
+ aBody = new BulletBody(prim.LocalID, bodyPtr);
ReferenceBody(aBody, true);
- prim.BSBody = aBody;
+ prim.PhysBody = aBody;
ret = true;
}
@@ -824,6 +955,42 @@ public class BSShapeCollection : IDisposable
return ret;
}
+ private bool TryGetMeshByPtr(IntPtr addr, out MeshDesc outDesc)
+ {
+ bool ret = false;
+ MeshDesc foundDesc = new MeshDesc();
+ foreach (MeshDesc md in Meshes.Values)
+ {
+ if (md.ptr == addr)
+ {
+ foundDesc = md;
+ ret = true;
+ break;
+ }
+
+ }
+ outDesc = foundDesc;
+ return ret;
+ }
+
+ private bool TryGetHullByPtr(IntPtr addr, out HullDesc outDesc)
+ {
+ bool ret = false;
+ HullDesc foundDesc = new HullDesc();
+ foreach (HullDesc hd in Hulls.Values)
+ {
+ if (hd.ptr == addr)
+ {
+ foundDesc = hd;
+ ret = true;
+ break;
+ }
+
+ }
+ outDesc = foundDesc;
+ return ret;
+ }
+
private void DetailLog(string msg, params Object[] args)
{
if (PhysicsScene.PhysicsLogging.Enabled)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
new file mode 100755
index 0000000000..5e2c4a8392
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public abstract class BSShape
+{
+ public IntPtr ptr { get; set; }
+ public ShapeData.PhysicsShapeType type { get; set; }
+ public System.UInt64 key { get; set; }
+ public int referenceCount { get; set; }
+ public DateTime lastReferenced { get; set; }
+
+ protected void Initialize()
+ {
+ ptr = IntPtr.Zero;
+ type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN;
+ key = 0;
+ referenceCount = 0;
+ lastReferenced = DateTime.Now;
+ }
+
+ // Get a reference to a physical shape. Create if it doesn't exist
+ public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
+ {
+ BSShape ret = null;
+
+ if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
+ {
+ // an avatar capsule is close to a native shape (it is not shared)
+ ret = BSShapeNative.GetReference(physicsScene, prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
+ ShapeData.FixedShapeKey.KEY_CAPSULE);
+ physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret);
+ }
+
+ // Compound shapes are handled special as they are rebuilt from scratch.
+ // This isn't too great a hardship since most of the child shapes will already been created.
+ if (ret == null && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND)
+ {
+ // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
+ ret = BSShapeCompound.GetReference(prim);
+ physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
+ }
+
+ if (ret == null)
+ ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
+
+ return ret;
+ }
+ public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
+ {
+ return null;
+ }
+ public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
+ {
+ return null;
+ }
+
+ // Release the use of a physical shape.
+ public abstract void Dereference(BSScene physicsScene);
+
+ // All shapes have a static call to get a reference to the physical shape
+ // protected abstract static BSShape GetReference();
+
+ public override string ToString()
+ {
+ StringBuilder buff = new StringBuilder();
+ buff.Append("");
+ return buff.ToString();
+ }
+}
+
+public class BSShapeNull : BSShape
+{
+ public BSShapeNull()
+ {
+ base.Initialize();
+ }
+ public static BSShape GetReference() { return new BSShapeNull(); }
+ public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ }
+}
+
+public class BSShapeNative : BSShape
+{
+ private static string LogHeader = "[BULLETSIM SHAPE NATIVE]";
+ public BSShapeNative()
+ {
+ base.Initialize();
+ }
+ public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim,
+ ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey)
+ {
+ // Native shapes are not shared and are always built anew.
+ return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
+ }
+
+ private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
+ ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey)
+ {
+ ShapeData nativeShapeData = new ShapeData();
+ nativeShapeData.Type = shapeType;
+ nativeShapeData.ID = prim.LocalID;
+ nativeShapeData.Scale = prim.Scale;
+ nativeShapeData.Size = prim.Scale;
+ nativeShapeData.MeshKey = (ulong)shapeKey;
+ nativeShapeData.HullKey = (ulong)shapeKey;
+
+
+ if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
+ {
+ ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale);
+ physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
+ }
+ else
+ {
+ ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData);
+ }
+ if (ptr == IntPtr.Zero)
+ {
+ physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
+ LogHeader, prim.LocalID, shapeType);
+ }
+ type = shapeType;
+ key = (UInt64)shapeKey;
+ }
+ // Make this reference to the physical shape go away since native shapes are not shared.
+ public override void Dereference(BSScene physicsScene)
+ {
+ // Native shapes are not tracked and are released immediately
+ physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
+ BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr);
+ ptr = IntPtr.Zero;
+ // Garbage collection will free up this instance.
+ }
+}
+
+public class BSShapeMesh : BSShape
+{
+ private static string LogHeader = "[BULLETSIM SHAPE MESH]";
+ private static Dictionary Meshes = new Dictionary();
+
+ public BSShapeMesh()
+ {
+ base.Initialize();
+ }
+ public static BSShape GetReference() { return new BSShapeNull(); }
+ public override void Dereference(BSScene physicsScene) { }
+}
+
+public class BSShapeHull : BSShape
+{
+ private static string LogHeader = "[BULLETSIM SHAPE HULL]";
+ private static Dictionary Hulls = new Dictionary();
+
+ public BSShapeHull()
+ {
+ base.Initialize();
+ }
+ public static BSShape GetReference() { return new BSShapeNull(); }
+ public override void Dereference(BSScene physicsScene) { }
+}
+
+public class BSShapeCompound : BSShape
+{
+ private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
+ public BSShapeCompound()
+ {
+ base.Initialize();
+ }
+ public static BSShape GetReference(BSPhysObject prim)
+ {
+ return new BSShapeNull();
+ }
+ public override void Dereference(BSScene physicsScene) { }
+}
+}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 880859a12d..7c34af29bd 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -40,7 +40,7 @@ using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
-public class BSTerrainManager
+public sealed class BSTerrainManager
{
static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
@@ -238,7 +238,7 @@ public class BSTerrainManager
DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,call,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
- BSScene.TaintCallback rebuildOperation = delegate()
+ PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateOrCreateTerrain:UpdateExisting", delegate()
{
if (MegaRegionParentPhysicsScene != null)
{
@@ -337,14 +337,7 @@ public class BSTerrainManager
BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
m_terrainModified = true;
- };
-
- // There is the option to do the changes now (we're already in 'taint time'), or
- // to do the Bullet operations later.
- if (inTaintTime)
- rebuildOperation();
- else
- PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation);
+ });
}
else
{
@@ -364,7 +357,7 @@ public class BSTerrainManager
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
// Code that must happen at taint-time
- BSScene.TaintCallback createOperation = delegate()
+ PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateOrCreateTerrain:NewTerrain", delegate()
{
DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y);
// Create a new mapInfo that will be filled with the new info
@@ -377,13 +370,7 @@ public class BSTerrainManager
UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true);
m_terrainModified = true;
- };
-
- // If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
- if (inTaintTime)
- createOperation();
- else
- PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation);
+ });
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 5ffd591264..07149d8c6a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -194,6 +194,7 @@ public struct ShapeData
// following defined by BulletSim
SHAPE_GROUNDPLANE = 20,
SHAPE_TERRAIN = 21,
+ SHAPE_COMPOUND = 22,
};
public uint ID;
public PhysicsShapeType Type;
@@ -299,6 +300,7 @@ public struct ConfigurationParameters
public float shouldEnableFrictionCaching;
public float numberOfSolverIterations;
+ public float linksetImplementation;
public float linkConstraintUseFrameOffset;
public float linkConstraintEnableTransMotor;
public float linkConstraintTransMotorMaxVel;
@@ -378,6 +380,7 @@ public enum CollisionFilterGroups : uint
BTerrainFilter = 1 << 11,
BRaycastFilter = 1 << 12,
BSolidFilter = 1 << 13,
+ BLinksetFilter = 1 << 14,
// The collsion filters and masked are defined in one place -- don't want them scattered
AvatarFilter = BCharacterFilter,
@@ -386,6 +389,8 @@ public enum CollisionFilterGroups : uint
ObjectMask = BAllFilter,
StaticObjectFilter = BStaticFilter,
StaticObjectMask = BAllFilter,
+ LinksetFilter = BLinksetFilter,
+ LinksetMask = BAllFilter & ~BLinksetFilter,
VolumeDetectFilter = BSensorTrigger,
VolumeDetectMask = ~BSensorTrigger,
TerrainFilter = BTerrainFilter,
@@ -395,8 +400,6 @@ public enum CollisionFilterGroups : uint
};
-
-
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
public enum ConstraintParams : int
@@ -611,13 +614,25 @@ public static extern bool IsNativeShape2(IntPtr shape);
public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
-public static extern IntPtr CreateCompoundShape2(IntPtr sim);
+public static extern IntPtr CreateCompoundShape2(IntPtr sim, bool enableDynamicAabbTree);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
-public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot);
+public static extern int GetNumberOfCompoundChildren2(IntPtr cShape);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
-public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
+public static extern void AddChildShapeToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern IntPtr GetChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id);
@@ -881,10 +896,10 @@ public static extern float GetCcdMotionThreshold2(IntPtr obj);
public static extern void SetCcdMotionThreshold2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
-public static extern float GetCcdSweepSphereRadius2(IntPtr obj);
+public static extern float GetCcdSweptSphereRadius2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
-public static extern void SetCcdSweepSphereRadius2(IntPtr obj, float val);
+public static extern void SetCcdSweptSphereRadius2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetUserPointer2(IntPtr obj);
@@ -906,6 +921,12 @@ public static extern Vector3 GetGravity2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void SetLinearDamping2(IntPtr obj, float lin_damping);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void SetAngularDamping2(IntPtr obj, float ang_damping);
+
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern float GetLinearDamping2(IntPtr obj);
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 0587054c23..34413e5ec4 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -257,6 +257,12 @@ namespace OpenSim.Region.Physics.Manager
/// Getting this returns the velocity calculated by physics scene updates, using factors such as target velocity,
/// time to accelerate and collisions.
///
+ public virtual Vector3 TargetVelocity
+ {
+ get { return Velocity; }
+ set { Velocity = value; }
+ }
+
public abstract Vector3 Velocity { get; set; }
public abstract Vector3 Torque { get; set; }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index c73655791b..319f6ab884 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -661,6 +661,20 @@ namespace OpenSim.Region.Physics.OdePlugin
set { return; }
}
+ public override Vector3 TargetVelocity
+ {
+ get
+ {
+ return m_taintTargetVelocity;
+ }
+
+ set
+ {
+ Velocity = value;
+ }
+ }
+
+
public override Vector3 Velocity
{
get
@@ -1394,4 +1408,4 @@ namespace OpenSim.Region.Physics.OdePlugin
m_eventsubscription += p;
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0fa247d338..be030af5db 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3963,17 +3963,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (m_TransferModule != null)
{
- byte[] bucket = new byte[] { (byte)item.Type };
+ byte[] bucket = new byte[1];
+ bucket[0] = (byte)item.Type;
GridInstantMessage msg = new GridInstantMessage(World,
- m_host.UUID, m_host.Name + ", an object owned by " +
- resolveName(m_host.OwnerID) + ",", destId,
+ m_host.OwnerID, m_host.Name, destId,
(byte)InstantMessageDialog.TaskInventoryOffered,
- false, item.Name + "\n" + m_host.Name + " is located at " +
+ false, item.Name+". "+m_host.Name+" is located at "+
World.RegionInfo.RegionName+" "+
m_host.AbsolutePosition.ToString(),
agentItem.ID, true, m_host.AbsolutePosition,
- bucket, true); // TODO: May actually send no timestamp
+ bucket, true);
m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
}
diff --git a/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs b/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs
index 4123f491bb..ff45d94b7a 100644
--- a/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs
+++ b/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs
@@ -67,10 +67,25 @@ namespace OpenSim.Server.Handlers.Asset
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
bool allowDelete = serverConfig.GetBoolean("AllowRemoteDelete", false);
+ bool allowDeleteAllTypes = serverConfig.GetBoolean("AllowRemoteDeleteAllTypes", false);
+
+ AllowedRemoteDeleteTypes allowedRemoteDeleteTypes;
+
+ if (!allowDelete)
+ {
+ allowedRemoteDeleteTypes = AllowedRemoteDeleteTypes.None;
+ }
+ else
+ {
+ if (allowDeleteAllTypes)
+ allowedRemoteDeleteTypes = AllowedRemoteDeleteTypes.All;
+ else
+ allowedRemoteDeleteTypes = AllowedRemoteDeleteTypes.MapTile;
+ }
server.AddStreamHandler(new AssetServerGetHandler(m_AssetService));
server.AddStreamHandler(new AssetServerPostHandler(m_AssetService));
- server.AddStreamHandler(new AssetServerDeleteHandler(m_AssetService, allowDelete));
+ server.AddStreamHandler(new AssetServerDeleteHandler(m_AssetService, allowedRemoteDeleteTypes));
MainConsole.Instance.Commands.AddCommand("Assets", false,
"show asset",
diff --git a/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs b/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs
index 0cfe5b17de..986394bf59 100644
--- a/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs
+++ b/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs
@@ -42,18 +42,32 @@ using OpenSim.Framework.Servers.HttpServer;
namespace OpenSim.Server.Handlers.Asset
{
+ ///
+ /// Remote deletes allowed.
+ ///
+ public enum AllowedRemoteDeleteTypes
+ {
+ None,
+ MapTile,
+ All
+ }
+
public class AssetServerDeleteHandler : BaseStreamHandler
{
- // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_AssetService;
- protected bool m_allowDelete;
- public AssetServerDeleteHandler(IAssetService service, bool allowDelete) :
+ ///
+ /// Asset types that can be deleted remotely.
+ ///
+ private AllowedRemoteDeleteTypes m_allowedTypes;
+
+ public AssetServerDeleteHandler(IAssetService service, AllowedRemoteDeleteTypes allowedTypes) :
base("DELETE", "/assets")
{
m_AssetService = service;
- m_allowDelete = allowDelete;
+ m_allowedTypes = allowedTypes;
}
public override byte[] Handle(string path, Stream request,
@@ -63,13 +77,32 @@ namespace OpenSim.Server.Handlers.Asset
string[] p = SplitParams(path);
- if (p.Length > 0 && m_allowDelete)
+ if (p.Length > 0)
{
- result = m_AssetService.Delete(p[0]);
+ if (m_allowedTypes != AllowedRemoteDeleteTypes.None)
+ {
+ string assetID = p[0];
+
+ AssetBase asset = m_AssetService.Get(assetID);
+ if (asset != null)
+ {
+ if (m_allowedTypes == AllowedRemoteDeleteTypes.All
+ || (int)(asset.Flags & AssetFlags.Maptile) != 0)
+ {
+ result = m_AssetService.Delete(assetID);
+ }
+ else
+ {
+ m_log.DebugFormat(
+ "[ASSET SERVER DELETE HANDLER]: Request to delete asset {0}, but type is {1} and allowed remote delete types are {2}",
+ assetID, (AssetFlags)asset.Flags, m_allowedTypes);
+ }
+ }
+ }
}
XmlSerializer xs = new XmlSerializer(typeof(bool));
return ServerUtils.SerializeResult(xs, result);
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index b1f0f7e84d..e7eb6fe924 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Services.AssetService
if (assetLoaderEnabled)
{
- m_log.DebugFormat("[ASSET]: Loading default asset set from {0}", loaderArgs);
+ m_log.DebugFormat("[ASSET SERVICE]: Loading default asset set from {0}", loaderArgs);
m_AssetLoader.ForEachDefaultXmlAsset(
loaderArgs,
@@ -197,20 +197,7 @@ namespace OpenSim.Services.AssetService
if (!UUID.TryParse(id, out assetID))
return false;
- AssetBase asset = m_Database.GetAsset(assetID);
- if (asset == null)
- return false;
-
- if ((int)(asset.Flags & AssetFlags.Maptile) != 0)
- {
- return m_Database.Delete(id);
- }
- else
- {
- m_log.DebugFormat("[ASSET SERVICE]: Request to delete asset {0}, but flags are not Maptile", id);
- }
-
- return false;
+ return m_Database.Delete(id);
}
}
}
\ No newline at end of file
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs
index e62bcb556d..a1d10ed5c5 100644
--- a/OpenSim/Services/AssetService/XAssetService.cs
+++ b/OpenSim/Services/AssetService/XAssetService.cs
@@ -194,21 +194,7 @@ namespace OpenSim.Services.AssetService
if (!UUID.TryParse(id, out assetID))
return false;
- AssetBase asset = m_Database.GetAsset(assetID);
- if (asset == null)
- return false;
-
- if ((int)(asset.Flags & AssetFlags.Maptile) != 0)
- {
- return m_Database.Delete(id);
- }
- else
- {
- m_log.DebugFormat("[XASSET SERVICE]: Request to delete asset {0}, but flags are not Maptile", id);
- }
-
- return false;
+ return m_Database.Delete(id);
}
}
-}
-
+}
\ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
index 19dffc35ac..5bcff4883d 100644
--- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
@@ -321,7 +321,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
args["teleport_flags"] = OSD.FromString(flags.ToString());
- OSDMap result = WebUtil.PostToService(uri, args, 20000);
+ OSDMap result = WebUtil.PostToService(uri, args, 80000);
if (result["Success"].AsBoolean())
{
OSDMap unpacked = (OSDMap)result["_Result"];
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
index 004311f2ef..7b84d55ded 100644
--- a/OpenSim/Services/HypergridService/GatekeeperService.cs
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -68,6 +68,7 @@ namespace OpenSim.Services.HypergridService
private static UUID m_ScopeID;
private static bool m_AllowTeleportsToAnyRegion;
private static string m_ExternalName;
+ private static Uri m_Uri;
private static GridRegion m_DefaultGatewayRegion;
public GatekeeperService(IConfigSource config, ISimulationService simService)
@@ -99,6 +100,15 @@ namespace OpenSim.Services.HypergridService
if (m_ExternalName != string.Empty && !m_ExternalName.EndsWith("/"))
m_ExternalName = m_ExternalName + "/";
+ try
+ {
+ m_Uri = new Uri(m_ExternalName);
+ }
+ catch
+ {
+ m_log.WarnFormat("[GATEKEEPER SERVICE]: Malformed gatekeeper address {0}", m_ExternalName);
+ }
+
Object[] args = new Object[] { config };
m_GridService = ServerUtils.LoadPlugin(gridService, args);
m_PresenceService = ServerUtils.LoadPlugin(presenceService, args);
@@ -433,7 +443,18 @@ namespace OpenSim.Services.HypergridService
string externalname = m_ExternalName.TrimEnd(trailing_slash);
m_log.DebugFormat("[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, externalname);
- return string.Equals(addressee, externalname, StringComparison.OrdinalIgnoreCase);
+ Uri uri;
+ try
+ {
+ uri = new Uri(addressee);
+ }
+ catch
+ {
+ m_log.DebugFormat("[GATEKEEPER SERVICE]: Visitor provided malformed service address {0}", addressee);
+ return false;
+ }
+
+ return string.Equals(uri.GetLeftPart(UriPartial.Authority), m_Uri.GetLeftPart(UriPartial.Authority), StringComparison.OrdinalIgnoreCase) ;
}
#endregion
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
index 556a0da49c..784f136bb0 100644
--- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Services.HypergridService
m_ConfigName = configName;
if (m_Database == null)
- m_log.WarnFormat("[XXX]: m_Database is null!");
+ m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: m_Database is null!");
//
// Try reading the [InventoryService] section, if it exists
@@ -301,7 +301,7 @@ namespace OpenSim.Services.HypergridService
public override bool AddFolder(InventoryFolderBase folder)
{
- m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder {0} {1}", folder.Name, folder.ParentID);
+ //m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder {0} {1}", folder.Name, folder.ParentID);
// Let's do a bit of sanity checking, more than the base service does
// make sure the given folder's parent folder exists under the suitcase tree of this user
@@ -323,7 +323,7 @@ namespace OpenSim.Services.HypergridService
public override bool UpdateFolder(InventoryFolderBase folder)
{
- m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version);
+ //m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version);
if (!IsWithinSuitcaseTree(folder.Owner, folder.ID))
{
m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: folder {0} not within Suitcase tree", folder.Name);
@@ -460,6 +460,15 @@ namespace OpenSim.Services.HypergridService
if (folders != null && folders.Length > 0)
return folders[0];
+
+ // OK, so the RootFolder type didn't work. Let's look for any type with parent UUID.Zero.
+ folders = m_Database.GetFolders(
+ new string[] { "agentID", "folderName", "parentFolderID" },
+ new string[] { principalID.ToString(), "My Inventory", UUID.Zero.ToString() });
+
+ if (folders != null && folders.Length > 0)
+ return folders[0];
+
return null;
}
@@ -584,7 +593,7 @@ namespace OpenSim.Services.HypergridService
{
if (a.Wearables[i][j].ItemID == itemID)
{
- m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: item {0} is a wearable", itemID);
+ //m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: item {0} is a wearable", itemID);
return true;
}
}
@@ -593,7 +602,7 @@ namespace OpenSim.Services.HypergridService
// Check attachments
if (a.GetAttachmentForItem(itemID) != null)
{
- m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: item {0} is an attachment", itemID);
+ //m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: item {0} is an attachment", itemID);
return true;
}
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 309dab4501..9abc5e4f72 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -400,16 +400,7 @@ namespace OpenSim.Services.InventoryService
public virtual bool MoveFolder(InventoryFolderBase folder)
{
- XInventoryFolder[] x = m_Database.GetFolders(
- new string[] { "folderID" },
- new string[] { folder.ID.ToString() });
-
- if (x.Length == 0)
- return false;
-
- x[0].parentFolderID = folder.ParentID;
-
- return m_Database.StoreFolder(x[0]);
+ return m_Database.MoveFolder(folder.ID.ToString(), folder.ParentID.ToString());
}
// We don't check the principal's ID here
diff --git a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
index bca5979e50..f9bf768da3 100644
--- a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
@@ -125,6 +125,7 @@ namespace OpenSim.Tests.Common.Mock
}
public bool MoveItem(string id, string newParent) { throw new NotImplementedException(); }
+ public bool MoveFolder(string id, string newParent) { throw new NotImplementedException(); }
public XInventoryItem[] GetActiveGestures(UUID principalID) { throw new NotImplementedException(); }
public int GetAssetPermissions(UUID principalID, UUID assetID) { throw new NotImplementedException(); }
}
diff --git a/ThirdPartyLicenses/Aurora-Sim.txt b/ThirdPartyLicenses/Aurora-Sim.txt
new file mode 100644
index 0000000000..162d552b90
--- /dev/null
+++ b/ThirdPartyLicenses/Aurora-Sim.txt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Contributors, http://aurora-sim.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Aurora-Sim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index 068061f60e..b76d3c638e 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -484,8 +484,15 @@ IntegrationService = "8002/OpenSim.Server.Handlers.dll:IntegrationServiceConnect
; *
[HGInventoryService]
; For the InventoryServiceInConnector
- LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
+ LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService"
+ ;; alternatives:
+ ;; HG1.5, more permissive, not recommended, but still supported
+ ;LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
+ ;; HG1.0, totally permissive, not recommended, but OK for grids with 100% trust
+ ;LocalServiceModule = "OpenSim.Services.InventoryService.dll:XInventoryService"
+
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
+ AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
HomeURI = "http://127.0.0.1:8002"
; * The interface that local users get when they are in other grids.
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index 98a14bab2f..1c7f0f083c 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -77,7 +77,19 @@ IntegrationService = "8002/OpenSim.Server.Handlers.dll:IntegrationServiceConnect
LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService"
DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
AssetLoaderArgs = "./assets/AssetSets.xml"
- AllowRemoteDelete = "false"
+
+ ; Allow maptile assets to remotely deleted by remote calls to the asset service.
+ ; There is no harm in having this as false - it just means that historical maptile assets are not deleted.
+ ; This only applies to maptiles served via the version 1 viewer mechanisms
+ ; Default is false
+ AllowRemoteDelete = false
+
+ ; Allow all assets to be remotely deleted.
+ ; Only set this to true if you are operating a grid where you control all calls to the asset service
+ ; (where a necessary condition is that you control all simulators) and you need this for admin purposes.
+ ; If set to true, AllowRemoteDelete = true is required as well.
+ ; Default is false.
+ AllowRemoteDeleteAllTypes = false
; * This configuration loads the inventory server modules. It duplicates
; * the function of the legacy inventory server
diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example
index 84de0ecab2..f28de437cd 100644
--- a/bin/config-include/StandaloneCommon.ini.example
+++ b/bin/config-include/StandaloneCommon.ini.example
@@ -47,36 +47,6 @@
DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
AssetLoaderArgs = "assets/AssetSets.xml"
-[HGInventoryService]
- HomeURI = "http://127.0.0.1:9000"
-
-[HGAssetService]
- HomeURI = "http://127.0.0.1:9000"
-
- ;; The asset types that this grid can export to / import from other grids.
- ;; Comma separated.
- ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely:
- ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText,
- ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh
- ;;
- ;; Leave blank or commented if you don't want to apply any restrictions.
- ;; A more strict, but still reasonable, policy may be to disallow the exchange
- ;; of scripts, like so:
- ; DisallowExport ="LSLText"
- ; DisallowImport ="LSLBytecode"
-
-
-[HGInventoryAccessModule]
- HomeURI = "http://127.0.0.1:9000"
- Gatekeeper = "http://127.0.0.1:9000"
-
- ;; If you want to protect your assets from being copied by foreign visitors
- ;; uncomment the next line. You may want to do this on sims that have licensed content.
- ; OutboundPermission = False
-
-[HGFriendsModule]
- ; User level required to be able to send friendship invitations to foreign users
- ;LevelHGFriends = 0;
[GridService]
;; For in-memory region storage (default)
@@ -97,11 +67,6 @@
;; change this to the address of your simulator
Gatekeeper="http://127.0.0.1:9000"
-[Messaging]
- ; === HG ONLY ===
- ;; change this to the address of your simulator
- Gatekeeper = "http://127.0.0.1:9000"
-
[LibraryModule]
; Set this if you want to change the name of the OpenSim Library
;LibraryName = "My World's Library"
@@ -140,41 +105,6 @@
;AllowedClients = ""
;DeniedClients = ""
-[GatekeeperService]
- ExternalName = "http://127.0.0.1:9000"
-
- ; Does this grid allow incoming links to any region in it?
- ; If false, HG TPs happen only to the Default regions specified in [GridService] section
- AllowTeleportsToAnyRegion = true
-
- ;; Regular expressions for controlling which client versions are accepted/denied.
- ;; An empty string means nothing is checked.
- ;;
- ;; Example 1: allow only these 3 types of clients (any version of them)
- ;; AllowedClients = "Imprudence|Hippo|Second Life"
- ;;
- ;; Example 2: allow all clients except these
- ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
- ;;
- ;; Note that these are regular expressions, so every character counts.
- ;; Also note that this is very weak security and should not be trusted as a reliable means
- ;; for keeping bad clients out; modified clients can fake their identifiers.
- ;;
- ;;
- ;AllowedClients = ""
- ;DeniedClients = ""
-
- ;; Are foreign visitors allowed?
- ;ForeignAgentsAllowed = true
- ;;
- ;; If ForeignAgentsAllowed is true, make exceptions using AllowExcept.
- ;; Leave blank or commented for no exceptions.
- ; AllowExcept = "http://griefer.com:8002, http://enemy.com:8002"
- ;;
- ;; If ForeignAgentsAllowed is false, make exceptions using DisallowExcept
- ;; Leave blank or commented for no exceptions.
- ; DisallowExcept = "http://myfriendgrid.com:8002, http://myboss.com:8002"
-
[FreeswitchService]
;; If FreeSWITCH is not being used then you don't need to set any of these parameters
@@ -279,6 +209,44 @@
; Example:
; Region_Test_1 = "DisallowForeigners"
+;;
+;; HG configurations
+;;
+[GatekeeperService]
+ ExternalName = "http://127.0.0.1:9000"
+
+ ; Does this grid allow incoming links to any region in it?
+ ; If false, HG TPs happen only to the Default regions specified in [GridService] section
+ AllowTeleportsToAnyRegion = true
+
+ ;; Regular expressions for controlling which client versions are accepted/denied.
+ ;; An empty string means nothing is checked.
+ ;;
+ ;; Example 1: allow only these 3 types of clients (any version of them)
+ ;; AllowedClients = "Imprudence|Hippo|Second Life"
+ ;;
+ ;; Example 2: allow all clients except these
+ ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
+ ;;
+ ;; Note that these are regular expressions, so every character counts.
+ ;; Also note that this is very weak security and should not be trusted as a reliable means
+ ;; for keeping bad clients out; modified clients can fake their identifiers.
+ ;;
+ ;;
+ ;AllowedClients = ""
+ ;DeniedClients = ""
+
+ ;; Are foreign visitors allowed?
+ ;ForeignAgentsAllowed = true
+ ;;
+ ;; If ForeignAgentsAllowed is true, make exceptions using AllowExcept.
+ ;; Leave blank or commented for no exceptions.
+ ; AllowExcept = "http://griefer.com:8002, http://enemy.com:8002"
+ ;;
+ ;; If ForeignAgentsAllowed is false, make exceptions using DisallowExcept
+ ;; Leave blank or commented for no exceptions.
+ ; DisallowExcept = "http://myfriendgrid.com:8002, http://myboss.com:8002"
+
[UserAgentService]
;; User level required to be contacted from other grids
;LevelOutsideContacts = 0
@@ -299,3 +267,57 @@
;; If ForeignTripsAllowed is true, make exceptions using AllowExcept.
;; Leave blank or commented for no exceptions.
; AllowExcept_Level_200 = "http://griefer.com:8002, http://enemy.com:8002"
+
+[HGInventoryService]
+ HomeURI = "http://127.0.0.1:9000"
+
+[HGAssetService]
+ HomeURI = "http://127.0.0.1:9000"
+
+ ;; The asset types that this grid can export to / import from other grids.
+ ;; Comma separated.
+ ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely:
+ ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText,
+ ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh
+ ;;
+ ;; Leave blank or commented if you don't want to apply any restrictions.
+ ;; A more strict, but still reasonable, policy may be to disallow the exchange
+ ;; of scripts, like so:
+ ; DisallowExport ="LSLText"
+ ; DisallowImport ="LSLBytecode"
+
+
+[HGInventoryAccessModule]
+ HomeURI = "http://127.0.0.1:9000"
+ Gatekeeper = "http://127.0.0.1:9000"
+
+ ;; If you want to protect your assets from being copied by foreign visitors
+ ;; uncomment the next line. You may want to do this on sims that have licensed content.
+ ;; true = allow exports, false = disallow exports. True by default.
+ ; OutboundPermission = True
+
+ ;; Send visual reminder to local users that their inventories are unavailable while they are traveling
+ ;; and available when they return. True by default.
+ ;RestrictInventoryAccessAbroad = True
+
+[HGFriendsModule]
+ ; User level required to be able to send friendship invitations to foreign users
+ ;LevelHGFriends = 0;
+
+[Messaging]
+ ; === HG ONLY ===
+ ;; change this to the address of your simulator
+ Gatekeeper = "http://127.0.0.1:9000"
+
+
+[EntityTransfer]
+ ;; User level from which local users are allowed to HG teleport. Default 0 (all users)
+ ;LevelHGTeleport = 0
+
+ ;; Are local users restricted from taking their appearance abroad?
+ ;; Default is no restrictions
+ ;RestrictAppearanceAbroad = false
+
+ ;; If appearance is restricted, which accounts' appearances are allowed to be exported?
+ ;; Comma-separated list of account names
+ AccountForAppearance = "Test User, Astronaut Smith"
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini
index 76d588c5be..195e780ccd 100644
--- a/bin/config-include/StandaloneHypergrid.ini
+++ b/bin/config-include/StandaloneHypergrid.ini
@@ -152,7 +152,13 @@
;; This greatly restricts the inventory operations while in other grids
[HGInventoryService]
; For the InventoryServiceInConnector
- LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
+ LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService"
+ ;; alternatives:
+ ;; HG1.5, more permissive, not recommended, but still supported
+ ;LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
+ ;; HG1.0, totally permissive, not recommended, but OK for grids with 100% trust
+ ;LocalServiceModule = "OpenSim.Services.InventoryService.dll:XInventoryService"
+
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index fbc83e64c7..51526a70b5 100755
Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index 65d3805bb3..8bb9d10257 100755
Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index 936368a4d9..1a07d6af84 100755
Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index 82fbad6966..bbdd3800c6 100755
Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ
diff --git a/bin/lib64/libopenjpeg-dotnet.dylib b/bin/lib64/libopenjpeg-dotnet.dylib
index 18ca868c65..91f7264fdb 100755
Binary files a/bin/lib64/libopenjpeg-dotnet.dylib and b/bin/lib64/libopenjpeg-dotnet.dylib differ