Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Application/OpenSimBase.cs OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.csavinationmerge
commit
3aa83738e2
|
@ -115,6 +115,8 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
|||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
List<IScene> createdScenes = new List<IScene>();
|
||||
|
||||
for (int i = 0; i < regionsToLoad.Length; i++)
|
||||
{
|
||||
IScene scene;
|
||||
|
@ -123,17 +125,22 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
|||
")");
|
||||
|
||||
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
||||
|
||||
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
||||
createdScenes.Add(scene);
|
||||
|
||||
if (changed)
|
||||
regionsToLoad[i].EstateSettings.Save();
|
||||
|
||||
if (scene != null)
|
||||
regionsToLoad[i].EstateSettings.Save();
|
||||
}
|
||||
|
||||
foreach (IScene scene in createdScenes)
|
||||
{
|
||||
scene.Start();
|
||||
|
||||
m_newRegionCreatedHandler = OnNewRegionCreated;
|
||||
if (m_newRegionCreatedHandler != null)
|
||||
{
|
||||
m_newRegionCreatedHandler = OnNewRegionCreated;
|
||||
if (m_newRegionCreatedHandler != null)
|
||||
{
|
||||
m_newRegionCreatedHandler(scene);
|
||||
}
|
||||
m_newRegionCreatedHandler(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -831,6 +831,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
IScene newScene;
|
||||
m_application.CreateRegion(region, out newScene);
|
||||
newScene.Start();
|
||||
|
||||
// If an access specification was provided, use it.
|
||||
// Otherwise accept the default.
|
||||
|
|
|
@ -136,5 +136,10 @@ namespace OpenSim.Framework
|
|||
ISceneObject DeserializeObject(string representation);
|
||||
|
||||
bool CheckClient(UUID agentID, System.Net.IPEndPoint ep);
|
||||
|
||||
/// <summary>
|
||||
/// Start the scene and associated scripts within it.
|
||||
/// </summary>
|
||||
void Start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -504,9 +504,6 @@ namespace OpenSim
|
|||
scene.SnmpService.LinkUp(scene);
|
||||
}
|
||||
|
||||
scene.Start();
|
||||
scene.StartScripts();
|
||||
|
||||
return clientServers;
|
||||
}
|
||||
|
||||
|
@ -835,6 +832,7 @@ namespace OpenSim
|
|||
ShutdownClientServer(whichRegion);
|
||||
IScene scene;
|
||||
CreateRegion(whichRegion, true, out scene);
|
||||
scene.Start();
|
||||
}
|
||||
|
||||
# region Setup methods
|
||||
|
|
|
@ -702,6 +702,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
|
||||
if (f != null)
|
||||
folder = m_Scene.InventoryService.GetFolder(f);
|
||||
|
||||
if(folder.Type == 14 || folder.Type == 16)
|
||||
{
|
||||
// folder.Type = 6;
|
||||
folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -621,7 +621,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
|||
{
|
||||
if (!WorkItem.Cancel())
|
||||
{
|
||||
WorkItem.Abort();
|
||||
WorkItem.Cancel(true);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
|
|
@ -142,10 +142,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
|||
|
||||
scene.RegisterModuleInterface<IGridService>(this);
|
||||
|
||||
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
|
||||
m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
|
||||
else
|
||||
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
|
||||
lock (m_LocalCache)
|
||||
{
|
||||
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
|
||||
m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
|
||||
else
|
||||
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
|
@ -153,8 +156,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
|||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_LocalCache[scene.RegionInfo.RegionID].Clear();
|
||||
m_LocalCache.Remove(scene.RegionInfo.RegionID);
|
||||
lock (m_LocalCache)
|
||||
{
|
||||
m_LocalCache[scene.RegionInfo.RegionID].Clear();
|
||||
m_LocalCache.Remove(scene.RegionInfo.RegionID);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
|
@ -191,12 +197,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
|||
|
||||
// First see if it's a neighbour, even if it isn't on this sim.
|
||||
// Neighbour data is cached in memory, so this is fast
|
||||
foreach (RegionCache rcache in m_LocalCache.Values)
|
||||
|
||||
lock (m_LocalCache)
|
||||
{
|
||||
region = rcache.GetRegionByPosition(x, y);
|
||||
if (region != null)
|
||||
foreach (RegionCache rcache in m_LocalCache.Values)
|
||||
{
|
||||
return region;
|
||||
region = rcache.GetRegionByPosition(x, y);
|
||||
if (region != null)
|
||||
{
|
||||
return region;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,12 +255,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
|||
{
|
||||
System.Text.StringBuilder caps = new System.Text.StringBuilder();
|
||||
|
||||
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
|
||||
lock (m_LocalCache)
|
||||
{
|
||||
caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key);
|
||||
List<GridRegion> regions = kvp.Value.GetNeighbours();
|
||||
foreach (GridRegion r in regions)
|
||||
caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize);
|
||||
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
|
||||
{
|
||||
caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key);
|
||||
List<GridRegion> regions = kvp.Value.GetNeighbours();
|
||||
foreach (GridRegion r in regions)
|
||||
caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize);
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output(caps.ToString());
|
||||
|
|
|
@ -396,10 +396,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (value)
|
||||
{
|
||||
if (!m_active)
|
||||
Start();
|
||||
Start(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This appears assymetric with Start() above but is not - setting m_active = false stops the loops
|
||||
// XXX: Possibly this should be in an explicit Stop() method for symmetry.
|
||||
m_active = false;
|
||||
}
|
||||
}
|
||||
|
@ -1361,10 +1363,18 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
Start(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the scene
|
||||
/// </summary>
|
||||
public void Start()
|
||||
/// <param name='startScripts'>
|
||||
/// Start the scripts within the scene.
|
||||
/// </param>
|
||||
public void Start(bool startScripts)
|
||||
{
|
||||
m_active = true;
|
||||
|
||||
|
@ -1401,6 +1411,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_heartbeatThread
|
||||
= Watchdog.StartThread(
|
||||
Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
|
||||
|
||||
StartScripts();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -562,6 +562,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
// This has to be here to fire the event
|
||||
|
|
|
@ -75,11 +75,11 @@ private sealed class BulletBodyUnman : BulletBody
|
|||
private sealed class BulletShapeUnman : BulletShape
|
||||
{
|
||||
public IntPtr ptr;
|
||||
public BulletShapeUnman(IntPtr xx, BSPhysicsShapeType typ)
|
||||
public BulletShapeUnman(IntPtr xx, BSPhysicsShapeType typ)
|
||||
: base()
|
||||
{
|
||||
ptr = xx;
|
||||
type = typ;
|
||||
shapeType = typ;
|
||||
}
|
||||
public override bool HasPhysicalShape
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ private sealed class BulletShapeUnman : BulletShape
|
|||
}
|
||||
public override BulletShape Clone()
|
||||
{
|
||||
return new BulletShapeUnman(ptr, type);
|
||||
return new BulletShapeUnman(ptr, shapeType);
|
||||
}
|
||||
public override bool ReferenceSame(BulletShape other)
|
||||
{
|
||||
|
@ -255,7 +255,7 @@ public override BulletShape CreateHullShape(BulletWorld world, int hullCount, fl
|
|||
{
|
||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||
return new BulletShapeUnman(
|
||||
BSAPICPP.CreateHullShape2(worldu.ptr, hullCount, hulls),
|
||||
BSAPICPP.CreateHullShape2(worldu.ptr, hullCount, hulls),
|
||||
BSPhysicsShapeType.SHAPE_HULL);
|
||||
}
|
||||
|
||||
|
@ -375,7 +375,7 @@ public override BulletShape DuplicateCollisionShape(BulletWorld world, BulletSha
|
|||
{
|
||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||
BulletShapeUnman srcShapeu = srcShape as BulletShapeUnman;
|
||||
return new BulletShapeUnman(BSAPICPP.DuplicateCollisionShape2(worldu.ptr, srcShapeu.ptr, id), srcShape.type);
|
||||
return new BulletShapeUnman(BSAPICPP.DuplicateCollisionShape2(worldu.ptr, srcShapeu.ptr, id), srcShape.shapeType);
|
||||
}
|
||||
|
||||
public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape)
|
||||
|
@ -1503,7 +1503,7 @@ public static extern void DestroyObject2(IntPtr sim, IntPtr obj);
|
|||
public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateTerrainShape2(uint id, Vector3 size, float minHeight, float maxHeight,
|
||||
public static extern IntPtr CreateTerrainShape2(uint id, Vector3 size, float minHeight, float maxHeight,
|
||||
[MarshalAs(UnmanagedType.LPArray)] float[] heightMap,
|
||||
float scaleFactor, float collisionMargin);
|
||||
|
||||
|
|
|
@ -81,11 +81,11 @@ private sealed class BulletBodyXNA : BulletBody
|
|||
private sealed class BulletShapeXNA : BulletShape
|
||||
{
|
||||
public CollisionShape shape;
|
||||
public BulletShapeXNA(CollisionShape xx, BSPhysicsShapeType typ)
|
||||
public BulletShapeXNA(CollisionShape xx, BSPhysicsShapeType typ)
|
||||
: base()
|
||||
{
|
||||
shape = xx;
|
||||
type = typ;
|
||||
shapeType = typ;
|
||||
}
|
||||
public override bool HasPhysicalShape
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ private sealed class BulletShapeXNA : BulletShape
|
|||
}
|
||||
public override BulletShape Clone()
|
||||
{
|
||||
return new BulletShapeXNA(shape, type);
|
||||
return new BulletShapeXNA(shape, shapeType);
|
||||
}
|
||||
public override bool ReferenceSame(BulletShape other)
|
||||
{
|
||||
|
@ -137,8 +137,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
internal int LastEntityProperty = 0;
|
||||
|
||||
internal EntityProperties[] UpdatedObjects;
|
||||
internal Dictionary<uint, GhostObject> specialCollisionObjects;
|
||||
|
||||
internal Dictionary<uint, GhostObject> specialCollisionObjects;
|
||||
|
||||
private static int m_collisionsThisFrame;
|
||||
private BSScene PhysicsScene { get; set; }
|
||||
|
||||
|
@ -151,7 +151,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="p"></param>
|
||||
/// <param name="p_2"></param>
|
||||
|
@ -174,7 +174,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
|
||||
TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain;
|
||||
world.AddConstraint(constraint, pDisableCollisionsBetweenLinkedObjects);
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
public override bool GetForceUpdateAllAabbs(BulletWorld pWorld) {
|
||||
DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
|
||||
return world.GetForceUpdateAllAabbs();
|
||||
|
||||
|
||||
}
|
||||
public override void SetForceUpdateAllAabbs(BulletWorld pWorld, bool pForce)
|
||||
{
|
||||
|
@ -404,7 +404,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion);
|
||||
mat._origin = vposition;
|
||||
collisionObject.SetWorldTransform(mat);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override Vector3 GetPosition(BulletBody pCollisionObject)
|
||||
|
@ -457,7 +457,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
{
|
||||
CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
|
||||
collisionObject.Activate(pforceactivation);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override Quaternion GetOrientation(BulletBody pCollisionObject)
|
||||
|
@ -486,7 +486,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
{
|
||||
CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
|
||||
return collisionObject.GetCcdSweptSphereRadius();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override IntPtr GetUserPointer(BulletBody pCollisionObject)
|
||||
|
@ -559,8 +559,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
|
||||
|
||||
public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2,
|
||||
Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot,
|
||||
public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2,
|
||||
Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot,
|
||||
bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
|
||||
|
||||
{
|
||||
|
@ -604,7 +604,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pWorld"></param>
|
||||
/// <param name="pBody1"></param>
|
||||
|
@ -824,7 +824,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
{
|
||||
RigidBody body = (pBody as BulletBodyXNA).rigidBody;
|
||||
float angularDamping = body.GetAngularDamping();
|
||||
body.SetDamping(lin_damping, angularDamping);
|
||||
body.SetDamping(lin_damping, angularDamping);
|
||||
}
|
||||
|
||||
public override float GetLinearDamping(BulletBody pBody)
|
||||
|
@ -907,7 +907,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
RigidBody bo = co as RigidBody;
|
||||
if (bo == null)
|
||||
{
|
||||
|
||||
|
||||
if (world.IsInWorld(co))
|
||||
{
|
||||
world.RemoveCollisionObject(co);
|
||||
|
@ -915,7 +915,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
if (world.IsInWorld(bo))
|
||||
{
|
||||
world.RemoveRigidBody(bo);
|
||||
|
@ -947,7 +947,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
|
||||
// TODO: Turn this from a reference copy to a Value Copy.
|
||||
BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSShapeTypeFromBroadPhaseNativeType(shape1.GetShapeType()));
|
||||
|
||||
|
||||
return shape2;
|
||||
}
|
||||
|
||||
|
@ -957,7 +957,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return false;
|
||||
}
|
||||
//(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
||||
|
||||
|
||||
public override BulletBody CreateBodyFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
|
||||
{
|
||||
CollisionWorld world = (pWorld as BulletWorldXNA).world;
|
||||
|
@ -993,11 +993,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
m_startWorldTransform = IndexedMatrix.Identity;
|
||||
*/
|
||||
body.SetUserPointer(pLocalID);
|
||||
|
||||
|
||||
return new BulletBodyXNA(pLocalID, body);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override BulletBody CreateBodyWithDefaultMotionState( BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
|
||||
{
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
public override Vector3 GetAnisotripicFriction(BulletConstraint pconstrain)
|
||||
{
|
||||
|
||||
/* TODO */
|
||||
/* TODO */
|
||||
return Vector3.Zero;
|
||||
}
|
||||
public override Vector3 SetAnisotripicFriction(BulletConstraint pconstrain, Vector3 frict) { /* TODO */ return Vector3.Zero; }
|
||||
|
@ -1035,7 +1035,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
{
|
||||
CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
|
||||
return collisionObject.IsStaticObject();
|
||||
|
||||
|
||||
}
|
||||
public override bool IsKinematicObject(BulletBody pCollisionObject)
|
||||
{
|
||||
|
@ -1098,10 +1098,10 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return new BulletWorldXNA(1, PhysicsScene, BSAPIXNA.Initialize2(worldExtent, configparms, maxCollisions, ref collisionArray, maxUpdates, ref updateArray, null));
|
||||
}
|
||||
|
||||
private static DiscreteDynamicsWorld Initialize2(Vector3 worldExtent,
|
||||
private static DiscreteDynamicsWorld Initialize2(Vector3 worldExtent,
|
||||
ConfigurationParameters[] o,
|
||||
int mMaxCollisionsPerFrame, ref CollisionDesc[] collisionArray,
|
||||
int mMaxUpdatesPerFrame, ref EntityProperties[] updateArray,
|
||||
int mMaxUpdatesPerFrame, ref EntityProperties[] updateArray,
|
||||
object mDebugLogCallbackHandle)
|
||||
{
|
||||
CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData();
|
||||
|
@ -1138,9 +1138,9 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
p.avatarCapsuleDepth = BSParam.AvatarCapsuleDepth;
|
||||
p.avatarCapsuleHeight = BSParam.AvatarCapsuleHeight;
|
||||
p.avatarContactProcessingThreshold = BSParam.AvatarContactProcessingThreshold;
|
||||
|
||||
|
||||
p.vehicleAngularDamping = BSParam.VehicleAngularDamping;
|
||||
|
||||
|
||||
p.maxPersistantManifoldPoolSize = o[0].maxPersistantManifoldPoolSize;
|
||||
p.maxCollisionAlgorithmPoolSize = o[0].maxCollisionAlgorithmPoolSize;
|
||||
p.shouldDisableContactPoolDynamicAllocation = o[0].shouldDisableContactPoolDynamicAllocation;
|
||||
|
@ -1160,7 +1160,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
p.linkConstraintSolverIterations = BSParam.LinkConstraintSolverIterations;
|
||||
p.physicsLoggingFrames = o[0].physicsLoggingFrames;
|
||||
DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo();
|
||||
|
||||
|
||||
DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration();
|
||||
CollisionDispatcher m_dispatcher = new CollisionDispatcher(cci);
|
||||
|
||||
|
@ -1263,7 +1263,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override float GetAngularMotionDisc(BulletShape pShape)
|
||||
|
@ -1353,10 +1353,10 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
CollisionShape shape = (pShape as BulletShapeXNA).shape;
|
||||
gObj.SetCollisionShape(shape);
|
||||
gObj.SetUserPointer(pLocalID);
|
||||
|
||||
|
||||
if (specialCollisionObjects.ContainsKey(pLocalID))
|
||||
specialCollisionObjects[pLocalID] = gObj;
|
||||
else
|
||||
else
|
||||
specialCollisionObjects.Add(pLocalID, gObj);
|
||||
|
||||
// TODO: Add to Special CollisionObjects!
|
||||
|
@ -1447,8 +1447,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return new BulletShapeXNA(ret, BSShapeTypeFromBroadPhaseNativeType(ret.GetShapeType()));
|
||||
}
|
||||
|
||||
public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) {
|
||||
|
||||
public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) {
|
||||
|
||||
if (cShape == null)
|
||||
return null;
|
||||
CompoundShape compoundShape = (cShape as BulletShapeXNA).shape as CompoundShape;
|
||||
|
@ -1456,7 +1456,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
BulletShape retShape = new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType()));
|
||||
|
||||
|
||||
return retShape;
|
||||
return retShape;
|
||||
}
|
||||
|
||||
public BSPhysicsShapeType BSShapeTypeFromBroadPhaseNativeType(BroadphaseNativeTypes pin)
|
||||
|
@ -1598,8 +1598,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return new BulletShapeXNA(m_planeshape, BSPhysicsShapeType.SHAPE_GROUNDPLANE);
|
||||
}
|
||||
|
||||
public override BulletConstraint Create6DofSpringConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2,
|
||||
Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot,
|
||||
public override BulletConstraint Create6DofSpringConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2,
|
||||
Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot,
|
||||
bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
|
||||
|
||||
{
|
||||
|
@ -1745,7 +1745,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
{
|
||||
DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
|
||||
CompoundShape compoundshape = new CompoundShape(false);
|
||||
|
||||
|
||||
compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin);
|
||||
int ii = 1;
|
||||
|
||||
|
@ -1761,7 +1761,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
int ender = ((ii + 4) + (vertexCount*3));
|
||||
for (int iii = ii + 4; iii < ender; iii+=3)
|
||||
{
|
||||
|
||||
|
||||
virts.Add(new IndexedVector3(pConvHulls[iii], pConvHulls[iii + 1], pConvHulls[iii +2]));
|
||||
}
|
||||
ConvexHullShape convexShape = new ConvexHullShape(virts, vertexCount);
|
||||
|
@ -1769,7 +1769,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
compoundshape.AddChildShape(ref childTrans, convexShape);
|
||||
ii += (vertexCount*3 + 4);
|
||||
}
|
||||
|
||||
|
||||
return new BulletShapeXNA(compoundshape, BSPhysicsShapeType.SHAPE_HULL);
|
||||
}
|
||||
|
||||
|
@ -1791,13 +1791,13 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
public override BulletShape CreateMeshShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats)
|
||||
{
|
||||
//DumpRaw(indices,verticesAsFloats,pIndicesCount,pVerticesCount);
|
||||
|
||||
|
||||
for (int iter = 0; iter < pVerticesCount; iter++)
|
||||
{
|
||||
if (verticesAsFloats[iter] > 0 && verticesAsFloats[iter] < 0.0001) verticesAsFloats[iter] = 0;
|
||||
if (verticesAsFloats[iter] < 0 && verticesAsFloats[iter] > -0.0001) verticesAsFloats[iter] = 0;
|
||||
}
|
||||
|
||||
|
||||
ObjectArray<int> indicesarr = new ObjectArray<int>(indices);
|
||||
ObjectArray<float> vertices = new ObjectArray<float>(verticesAsFloats);
|
||||
DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount);
|
||||
|
@ -1811,7 +1811,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
mesh.m_vertexStride = 3;
|
||||
mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT;
|
||||
mesh.m_triangleIndexStride = 3;
|
||||
|
||||
|
||||
TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray();
|
||||
tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER);
|
||||
BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true);
|
||||
|
@ -1822,7 +1822,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
|
||||
{
|
||||
|
||||
|
||||
String fileName = "objTest3.raw";
|
||||
String completePath = System.IO.Path.Combine(Util.configDir(), fileName);
|
||||
StreamWriter sw = new StreamWriter(completePath);
|
||||
|
@ -1848,7 +1848,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
string s = vertices[indices[i * 3]].ToString("0.0000");
|
||||
s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000");
|
||||
s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000");
|
||||
|
||||
|
||||
sw.Write(s + "\n");
|
||||
}
|
||||
|
||||
|
@ -1870,7 +1870,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
mesh.m_vertexStride = 3;
|
||||
mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT;
|
||||
mesh.m_triangleIndexStride = 3;
|
||||
|
||||
|
||||
TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray();
|
||||
tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER);
|
||||
|
||||
|
@ -1901,7 +1901,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
sw.Close();
|
||||
}
|
||||
|
||||
public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
|
||||
public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
|
||||
float scaleFactor, float collisionMargin)
|
||||
{
|
||||
const int upAxis = 2;
|
||||
|
@ -1943,14 +1943,14 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
/* TODO */
|
||||
updatedEntityCount = 0;
|
||||
collidersCount = 0;
|
||||
|
||||
|
||||
|
||||
int ret = PhysicsStep2(world,timeStep,maxSubSteps,fixedTimeStep,out updatedEntityCount,out world.physicsScene.m_updateArray, out collidersCount, out world.physicsScene.m_collisionArray);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int PhysicsStep2(BulletWorld pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep,
|
||||
private int PhysicsStep2(BulletWorld pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep,
|
||||
out int updatedEntityCount, out EntityProperties[] updatedEntities,
|
||||
out int collidersCount, out CollisionDesc[] colliders)
|
||||
{
|
||||
|
@ -1959,24 +1959,24 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return epic;
|
||||
}
|
||||
|
||||
private int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount,
|
||||
private int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount,
|
||||
out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates)
|
||||
{
|
||||
int numSimSteps = 0;
|
||||
Array.Clear(UpdatedObjects, 0, UpdatedObjects.Length);
|
||||
Array.Clear(UpdatedCollisions, 0, UpdatedCollisions.Length);
|
||||
LastEntityProperty=0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LastCollisionDesc=0;
|
||||
|
||||
|
||||
updatedEntityCount = 0;
|
||||
collidersCount = 0;
|
||||
|
||||
|
||||
|
||||
if (pWorld is BulletWorldXNA)
|
||||
{
|
||||
|
@ -2033,7 +2033,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
|
||||
collidersCount = LastCollisionDesc;
|
||||
colliders = UpdatedCollisions;
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -2041,15 +2041,15 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
//if (updatedEntities is null)
|
||||
//updatedEntities = new List<BulletXNA.EntityProperties>();
|
||||
//updatedEntityCount = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
//collidersCount = 0;
|
||||
|
||||
|
||||
updatedEntities = new EntityProperties[0];
|
||||
|
||||
|
||||
|
||||
colliders = new CollisionDesc[0];
|
||||
|
||||
|
||||
}
|
||||
return numSimSteps;
|
||||
}
|
||||
|
@ -2057,7 +2057,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
{
|
||||
IOverlappingPairCache cache = obj.GetOverlappingPairCache();
|
||||
ObjectArray<BroadphasePair> pairs = cache.GetOverlappingPairArray();
|
||||
|
||||
|
||||
DiscreteDynamicsWorld world = (PhysicsScene.World as BulletWorldXNA).world;
|
||||
PersistentManifoldArray manifoldArray = new PersistentManifoldArray();
|
||||
BroadphasePair collisionPair;
|
||||
|
@ -2069,7 +2069,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
ManifoldPoint pt;
|
||||
|
||||
int numPairs = pairs.Count;
|
||||
|
||||
|
||||
for (int i = 0; i < numPairs; i++)
|
||||
{
|
||||
manifoldArray.Clear();
|
||||
|
@ -2078,7 +2078,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
collisionPair = world.GetPairCache().FindPair(pairs[i].m_pProxy0, pairs[i].m_pProxy1);
|
||||
if (collisionPair == null)
|
||||
continue;
|
||||
|
||||
|
||||
collisionPair.m_algorithm.GetAllContactManifolds(manifoldArray);
|
||||
for (int j = 0; j < manifoldArray.Count; j++)
|
||||
{
|
||||
|
@ -2101,7 +2101,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
}
|
||||
private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm, float penetration)
|
||||
{
|
||||
|
||||
|
||||
IndexedVector3 contactNormal = norm;
|
||||
if ((objA.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0 &&
|
||||
(objB.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0)
|
||||
|
@ -2171,11 +2171,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
if (NotMe is BulletBodyXNA && NotMe.HasPhysicalBody)
|
||||
{
|
||||
CollisionObject AvoidBody = (NotMe as BulletBodyXNA).body;
|
||||
|
||||
|
||||
IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z);
|
||||
IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight);
|
||||
using (
|
||||
ClosestNotMeRayResultCallback rayCallback =
|
||||
ClosestNotMeRayResultCallback rayCallback =
|
||||
new ClosestNotMeRayResultCallback(rOrigin, rEnd, AvoidBody)
|
||||
)
|
||||
{
|
||||
|
@ -2191,9 +2191,9 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class SimMotionState : DefaultMotionState
|
||||
{
|
||||
|
@ -2286,12 +2286,12 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
m_lastProperties = m_properties;
|
||||
if (m_world.LastEntityProperty < m_world.UpdatedObjects.Length)
|
||||
m_world.UpdatedObjects[m_world.LastEntityProperty++]=(m_properties);
|
||||
|
||||
|
||||
//(*m_updatesThisFrame)[m_properties.ID] = &m_properties;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
public override void SetRigidBody(RigidBody body)
|
||||
|
@ -2314,7 +2314,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
(((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))) &&
|
||||
(((v1.W - nEpsilon) < v2.W) && (v2.W < (v1.W + nEpsilon)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,8 +87,8 @@ public class BSActorAvatarMove : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ public class BSActorAvatarMove : BSActor
|
|||
if (m_velocityMotor == null)
|
||||
{
|
||||
// Infinite decay and timescale values so motor only changes current to target values.
|
||||
m_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
||||
m_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
||||
0.2f, // time scale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
|
|
|
@ -87,8 +87,8 @@ public class BSActorHover : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public class BSActorLockAxis : BSActor
|
|||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}",
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}",
|
||||
m_controllingPrim.LocalID, m_controllingPrim.LockedAxis, Enabled, m_controllingPrim.IsPhysicallyActive);
|
||||
// If all the axis are free, we don't need to exist
|
||||
if (m_controllingPrim.LockedAxis == m_controllingPrim.LockedAxisFree)
|
||||
|
@ -85,8 +85,8 @@ public class BSActorLockAxis : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
|
|
|
@ -88,8 +88,8 @@ public class BSActorMoveToTarget : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the moveToTarget since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ public class BSActorSetForce : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ public class BSActorSetTorque : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -106,9 +106,9 @@ public class BSActorCollection
|
|||
{
|
||||
ForEachActor(a => a.Refresh());
|
||||
}
|
||||
public void RemoveBodyDependencies()
|
||||
public void RemoveDependencies()
|
||||
{
|
||||
ForEachActor(a => a.RemoveBodyDependencies());
|
||||
ForEachActor(a => a.RemoveDependencies());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ public class BSActorCollection
|
|||
/// Each physical object can have 'actors' who are pushing the object around.
|
||||
/// This can be used for hover, locking axis, making vehicles, etc.
|
||||
/// Each physical object can have multiple actors acting on it.
|
||||
///
|
||||
///
|
||||
/// An actor usually registers itself with physics scene events (pre-step action)
|
||||
/// and modifies the parameters on the host physical object.
|
||||
/// </summary>
|
||||
|
@ -154,7 +154,7 @@ public abstract class BSActor
|
|||
public abstract void Refresh();
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
public abstract void RemoveBodyDependencies();
|
||||
public abstract void RemoveDependencies();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,7 +298,7 @@ public abstract class BSAPITemplate
|
|||
{
|
||||
// Returns the name of the underlying Bullet engine
|
||||
public abstract string BulletEngineName { get; }
|
||||
public abstract string BulletEngineVersion { get; protected set;}
|
||||
public abstract string BulletEngineVersion { get; protected set;}
|
||||
|
||||
// Initialization and simulation
|
||||
public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms,
|
||||
|
@ -373,7 +373,7 @@ public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
|
|||
// =====================================================================================
|
||||
public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin);
|
||||
|
||||
public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
|
||||
public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
|
||||
float scaleFactor, float collisionMargin);
|
||||
|
||||
// =====================================================================================
|
||||
|
@ -388,7 +388,7 @@ public abstract BulletConstraint Create6DofConstraintToPoint(BulletWorld world,
|
|||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||
|
||||
public abstract BulletConstraint Create6DofConstraintFixed(BulletWorld world, BulletBody obj1,
|
||||
Vector3 frameInBloc, Quaternion frameInBrot,
|
||||
Vector3 frameInBloc, Quaternion frameInBrot,
|
||||
bool useLinearReferenceFrameB, bool disableCollisionsBetweenLinkedBodies);
|
||||
|
||||
public abstract BulletConstraint Create6DofSpringConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2,
|
||||
|
|
|
@ -95,18 +95,18 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// the avatar seeking to reach the motor's target speed.
|
||||
// This motor runs as a prestep action for the avatar so it will keep the avatar
|
||||
// standing as well as moving. Destruction of the avatar will destroy the pre-step action.
|
||||
m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName);
|
||||
m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName);
|
||||
PhysicalActors.Add(AvatarMoveActorName, m_moveActor);
|
||||
|
||||
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
|
||||
|
||||
// do actual creation in taint time
|
||||
PhysicsScene.TaintedObject("BSCharacter.create", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.create", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.create,taint", LocalID);
|
||||
// New body and shape into PhysBody and PhysShape
|
||||
PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this);
|
||||
PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this);
|
||||
|
||||
SetPhysicalProperties();
|
||||
});
|
||||
|
@ -119,18 +119,18 @@ public sealed class BSCharacter : BSPhysObject
|
|||
base.Destroy();
|
||||
|
||||
DetailLog("{0},BSCharacter.Destroy", LocalID);
|
||||
PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.destroy", delegate()
|
||||
{
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
|
||||
PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, null /* bodyCallback */);
|
||||
PhysShape.Clear();
|
||||
PhysShape.Dereference(PhysScene);
|
||||
PhysShape = new BSShapeNull();
|
||||
});
|
||||
}
|
||||
|
||||
private void SetPhysicalProperties()
|
||||
{
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
|
||||
|
||||
ZeroMotion(true);
|
||||
ForcePosition = _position;
|
||||
|
@ -145,35 +145,35 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// Needs to be reset especially when an avatar is recreated after crossing a region boundry.
|
||||
Flying = _flying;
|
||||
|
||||
PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution);
|
||||
PhysicsScene.PE.SetMargin(PhysShape, PhysicsScene.Params.collisionMargin);
|
||||
PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
PhysScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution);
|
||||
PhysScene.PE.SetMargin(PhysShape.physShapeInfo, PhysScene.Params.collisionMargin);
|
||||
PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
|
||||
PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
if (BSParam.CcdMotionThreshold > 0f)
|
||||
{
|
||||
PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
|
||||
PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
|
||||
PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
|
||||
PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
|
||||
}
|
||||
|
||||
UpdatePhysicalMassProperties(RawMass, false);
|
||||
|
||||
// Make so capsule does not fall over
|
||||
PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero);
|
||||
PhysScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero);
|
||||
|
||||
// The avatar mover sets some parameters.
|
||||
PhysicalActors.Refresh();
|
||||
|
||||
PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT);
|
||||
PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT);
|
||||
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.AddObjectToWorld(PhysScene.World, PhysBody);
|
||||
|
||||
// PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
|
||||
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION);
|
||||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION);
|
||||
PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody);
|
||||
|
||||
// Do this after the object has been added to the world
|
||||
PhysBody.collisionType = CollisionType.Avatar;
|
||||
PhysBody.ApplyCollisionMask(PhysicsScene);
|
||||
PhysBody.ApplyCollisionMask(PhysScene);
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,14 +203,14 @@ public sealed class BSCharacter : BSPhysObject
|
|||
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
|
||||
|
||||
PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.setSize", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape)
|
||||
if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
|
||||
{
|
||||
PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
|
||||
PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
|
||||
UpdatePhysicalMassProperties(RawMass, true);
|
||||
// Make sure this change appears as a property update event
|
||||
PhysicsScene.PE.PushUpdate(PhysBody);
|
||||
PhysScene.PE.PushUpdate(PhysBody);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -221,11 +221,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
set { BaseShape = value; }
|
||||
}
|
||||
// I want the physics engine to make an avatar capsule
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||
{
|
||||
get {return BSPhysicsShapeType.SHAPE_CAPSULE; }
|
||||
}
|
||||
|
||||
public override bool Grabbed {
|
||||
set { _grabbed = value; }
|
||||
|
@ -252,24 +247,24 @@ public sealed class BSCharacter : BSPhysObject
|
|||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
|
||||
// Zero some other properties directly into the physics engine
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.ClearAllForces(PhysBody);
|
||||
PhysScene.PE.ClearAllForces(PhysBody);
|
||||
});
|
||||
}
|
||||
public override void ZeroAngularMotion(bool inTaintTime)
|
||||
{
|
||||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero);
|
||||
PhysicsScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero);
|
||||
PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero);
|
||||
PhysScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero);
|
||||
// The next also get rid of applied linear force but the linear velocity is untouched.
|
||||
PhysicsScene.PE.ClearForces(PhysBody);
|
||||
PhysScene.PE.ClearForces(PhysBody);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -291,7 +286,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
set {
|
||||
_position = value;
|
||||
|
||||
PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.setPosition", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
PositionSanityCheck();
|
||||
|
@ -301,14 +296,14 @@ public sealed class BSCharacter : BSPhysObject
|
|||
}
|
||||
public override OMV.Vector3 ForcePosition {
|
||||
get {
|
||||
_position = PhysicsScene.PE.GetPosition(PhysBody);
|
||||
_position = PhysScene.PE.GetPosition(PhysBody);
|
||||
return _position;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -322,18 +317,18 @@ public sealed class BSCharacter : BSPhysObject
|
|||
bool ret = false;
|
||||
|
||||
// TODO: check for out of bounds
|
||||
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||
if (!PhysScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||
{
|
||||
// The character is out of the known/simulated area.
|
||||
// Force the avatar position to be within known. ScenePresence will use the position
|
||||
// plus the velocity to decide if the avatar is moving out of the region.
|
||||
RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition);
|
||||
RawPosition = PhysScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition);
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
// If below the ground, move the avatar up
|
||||
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
|
||||
float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
|
||||
if (Position.Z < terrainHeight)
|
||||
{
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
||||
|
@ -342,7 +337,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
}
|
||||
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
||||
{
|
||||
float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||
if (Position.Z < waterHeight)
|
||||
{
|
||||
_position.Z = waterHeight;
|
||||
|
@ -363,7 +358,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
// The new position value must be pushed into the physics engine but we can't
|
||||
// just assign to "Position" because of potential call loops.
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
ForcePosition = _position;
|
||||
|
@ -376,13 +371,13 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override float Mass { get { return _mass; } }
|
||||
|
||||
// used when we only want this prim's mass and not the linkset thing
|
||||
public override float RawMass {
|
||||
public override float RawMass {
|
||||
get {return _mass; }
|
||||
}
|
||||
public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
|
||||
{
|
||||
OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
|
||||
PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia);
|
||||
OMV.Vector3 localInertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
|
||||
PhysScene.PE.SetMassProps(PhysBody, physMass, localInertia);
|
||||
}
|
||||
|
||||
public override OMV.Vector3 Force {
|
||||
|
@ -390,11 +385,11 @@ public sealed class BSCharacter : BSPhysObject
|
|||
set {
|
||||
RawForce = value;
|
||||
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
||||
PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.SetForce", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.SetObjectForce(PhysBody, RawForce);
|
||||
PhysScene.PE.SetObjectForce(PhysBody, RawForce);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -437,7 +432,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
set {
|
||||
RawVelocity = value;
|
||||
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
|
||||
PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.setVelocity", delegate()
|
||||
{
|
||||
if (m_moveActor != null)
|
||||
m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
|
||||
|
@ -450,11 +445,11 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override OMV.Vector3 ForceVelocity {
|
||||
get { return RawVelocity; }
|
||||
set {
|
||||
PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity");
|
||||
PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity");
|
||||
|
||||
RawVelocity = value;
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
|
||||
PhysicsScene.PE.Activate(PhysBody, true);
|
||||
PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
|
||||
PhysScene.PE.Activate(PhysBody, true);
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 Torque {
|
||||
|
@ -484,7 +479,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
if (_orientation != value)
|
||||
{
|
||||
_orientation = value;
|
||||
PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||
{
|
||||
ForceOrientation = _orientation;
|
||||
});
|
||||
|
@ -496,7 +491,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
get
|
||||
{
|
||||
_orientation = PhysicsScene.PE.GetOrientation(PhysBody);
|
||||
_orientation = PhysScene.PE.GetOrientation(PhysBody);
|
||||
return _orientation;
|
||||
}
|
||||
set
|
||||
|
@ -505,7 +500,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
// _position = PhysicsScene.PE.GetPosition(BSBody);
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -554,14 +549,14 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override bool FloatOnWater {
|
||||
set {
|
||||
_floatOnWater = value;
|
||||
PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.setFloatOnWater", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
if (_floatOnWater)
|
||||
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
else
|
||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -582,7 +577,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override float Buoyancy {
|
||||
get { return _buoyancy; }
|
||||
set { _buoyancy = value;
|
||||
PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
|
||||
PhysScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
ForceBuoyancy = _buoyancy;
|
||||
|
@ -591,8 +586,8 @@ public sealed class BSCharacter : BSPhysObject
|
|||
}
|
||||
public override float ForceBuoyancy {
|
||||
get { return _buoyancy; }
|
||||
set {
|
||||
PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy");
|
||||
set {
|
||||
PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy");
|
||||
|
||||
_buoyancy = value;
|
||||
DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
|
@ -600,7 +595,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
float grav = BSParam.Gravity * (1f - _buoyancy);
|
||||
Gravity = new OMV.Vector3(0f, 0f, grav);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.SetGravity(PhysBody, Gravity);
|
||||
PhysScene.PE.SetGravity(PhysBody, Gravity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,7 +613,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override void AddForce(OMV.Vector3 force, bool pushforce)
|
||||
{
|
||||
// Since this force is being applied in only one step, make this a force per second.
|
||||
OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
|
||||
OMV.Vector3 addForce = force / PhysScene.LastTimeStep;
|
||||
AddForce(addForce, pushforce, false);
|
||||
}
|
||||
private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
|
@ -627,13 +622,13 @@ public sealed class BSCharacter : BSPhysObject
|
|||
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
|
||||
// DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
|
||||
{
|
||||
// Bullet adds this central force to the total force for this tick
|
||||
// DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
|
||||
PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -652,7 +647,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
|
||||
{
|
||||
OMV.Vector3 newScale;
|
||||
|
||||
|
||||
// Bullet's capsule total height is the "passed height + radius * 2";
|
||||
// The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1)
|
||||
// The number we pass in for 'scaling' is the multiplier to get that base
|
||||
|
|
|
@ -45,7 +45,7 @@ public sealed class BSConstraintHinge : BSConstraint
|
|||
m_body1 = obj1;
|
||||
m_body2 = obj2;
|
||||
m_constraint = PhysicsScene.PE.CreateHingeConstraint(world, obj1, obj2,
|
||||
pivotInA, pivotInB, axisInA, axisInB,
|
||||
pivotInA, pivotInB, axisInA, axisInB,
|
||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
|
||||
m_enabled = true;
|
||||
}
|
||||
|
|
|
@ -559,9 +559,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
break;
|
||||
}
|
||||
|
||||
// Update any physical parameters based on this type.
|
||||
Refresh();
|
||||
|
||||
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
||||
m_linearMotorDecayTimescale, m_linearFrictionTimescale,
|
||||
1f);
|
||||
|
@ -589,6 +586,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
RegisterForSceneEvents();
|
||||
}
|
||||
|
||||
// Update any physical parameters based on this type.
|
||||
Refresh();
|
||||
}
|
||||
#endregion // Vehicle parameter setting
|
||||
|
||||
|
@ -596,6 +596,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
public override void Refresh()
|
||||
{
|
||||
// If asking for a refresh, reset the physical parameters before the next simulation step.
|
||||
// Called whether active or not since the active state may be updated before the next step.
|
||||
m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
|
||||
{
|
||||
SetPhysicalParameters();
|
||||
|
@ -625,7 +626,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Vehicles report collision events so we know when it's on the ground
|
||||
m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
|
||||
ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape, m_vehicleMass);
|
||||
ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
|
||||
m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
|
||||
m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
|
||||
|
||||
|
@ -649,7 +650,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
|
||||
// BSActor.RemoveBodyDependencies
|
||||
public override void RemoveBodyDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
@ -789,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
|
||||
{
|
||||
lastRememberedHeightPos = pos;
|
||||
m_knownTerrainHeight = ControllingPrim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||
m_knownTerrainHeight = ControllingPrim.PhysScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||
m_knownHas |= m_knownChangedTerrainHeight;
|
||||
}
|
||||
return m_knownTerrainHeight;
|
||||
|
@ -801,7 +802,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
if ((m_knownHas & m_knownChangedWaterLevel) == 0)
|
||||
{
|
||||
m_knownWaterLevel = ControllingPrim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos);
|
||||
m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos);
|
||||
m_knownHas |= m_knownChangedWaterLevel;
|
||||
}
|
||||
return (float)m_knownWaterLevel;
|
||||
|
@ -1019,7 +1020,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG
|
||||
VehicleVelocity /= VehicleVelocity.Length();
|
||||
VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
|
||||
VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
|
||||
VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
|
||||
ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
|
||||
}
|
||||
else if (newVelocityLengthSq < 0.001f)
|
||||
|
@ -1094,7 +1095,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if (VehiclePosition.Z > m_VhoverTargetHeight)
|
||||
m_VhoverTargetHeight = VehiclePosition.Z;
|
||||
}
|
||||
|
||||
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
{
|
||||
if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f)
|
||||
|
@ -1188,7 +1189,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// used with conjunction with banking: the strength of the banking will decay when the
|
||||
// vehicle no longer experiences collisions. The decay timescale is the same as
|
||||
// VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering
|
||||
// when they are in mid jump.
|
||||
// when they are in mid jump.
|
||||
// TODO: this code is wrong. Also, what should it do for boats (height from water)?
|
||||
// This is just using the ground and a general collision check. Should really be using
|
||||
// a downward raycast to find what is below.
|
||||
|
@ -1254,7 +1255,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
VehicleAddForce(appliedGravity);
|
||||
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
|
||||
ControllingPrim.LocalID, m_VehicleGravity,
|
||||
ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
|
||||
}
|
||||
|
@ -1330,7 +1331,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
|
||||
// This flag prevents linear deflection parallel to world z-axis. This is useful
|
||||
// for preventing ground vehicles with large linear deflection, like bumper cars,
|
||||
// from climbing their linear deflection into the sky.
|
||||
// from climbing their linear deflection into the sky.
|
||||
// That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
||||
// TODO: This is here because this is where ODE put it but documentation says it
|
||||
// is a linear effect. Where should this check go?
|
||||
|
@ -1463,7 +1464,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
|
||||
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
|
||||
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
|
||||
m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
|
||||
*/
|
||||
}
|
||||
|
@ -1530,13 +1531,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude
|
||||
// of the yaw effect will be proportional to the
|
||||
// VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's
|
||||
// velocity along its preferred axis of motion.
|
||||
// velocity along its preferred axis of motion.
|
||||
// The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any
|
||||
// positive rotation (by the right-hand rule) about the roll-axis will effect a
|
||||
// (negative) torque around the yaw-axis, making it turn to the right--that is the
|
||||
// vehicle will lean into the turn, which is how real airplanes and motorcycle's work.
|
||||
// Negating the banking coefficient will make it so that the vehicle leans to the
|
||||
// outside of the turn (not very "physical" but might allow interesting vehicles so why not?).
|
||||
// outside of the turn (not very "physical" but might allow interesting vehicles so why not?).
|
||||
// The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making
|
||||
// banking vehicles do what you want rather than what the laws of physics allow.
|
||||
// For example, consider a real motorcycle...it must be moving forward in order for
|
||||
|
@ -1548,11 +1549,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// totally static (0.0) and totally dynamic (1.0). By "static" we mean that the
|
||||
// banking effect depends only on the vehicle's rotation about its roll-axis compared
|
||||
// to "dynamic" where the banking is also proportional to its velocity along its
|
||||
// roll-axis. Finding the best value of the "mixture" will probably require trial and error.
|
||||
// roll-axis. Finding the best value of the "mixture" will probably require trial and error.
|
||||
// The time it takes for the banking behavior to defeat a preexisting angular velocity about the
|
||||
// world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to
|
||||
// bank quickly then give it a banking timescale of about a second or less, otherwise you can
|
||||
// make a sluggish vehicle by giving it a timescale of several seconds.
|
||||
// make a sluggish vehicle by giving it a timescale of several seconds.
|
||||
public void ComputeAngularBanking()
|
||||
{
|
||||
if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
|
@ -1581,7 +1582,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
//VehicleRotationalVelocity += bankingContributionV * VehicleOrientation;
|
||||
VehicleRotationalVelocity += bankingContributionV;
|
||||
|
||||
|
||||
|
||||
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
|
||||
ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
|
||||
|
@ -1637,8 +1638,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Invoke the detailed logger and output something if it's enabled.
|
||||
private void VDetailLog(string msg, params Object[] args)
|
||||
{
|
||||
if (ControllingPrim.PhysicsScene.VehicleLoggingEnabled)
|
||||
ControllingPrim.PhysicsScene.DetailLog(msg, args);
|
||||
if (ControllingPrim.PhysScene.VehicleLoggingEnabled)
|
||||
ControllingPrim.PhysScene.DetailLog(msg, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public abstract class BSLinkset
|
|||
|
||||
public BSPrimLinkable LinksetRoot { get; protected set; }
|
||||
|
||||
public BSScene PhysicsScene { get; private set; }
|
||||
protected BSScene m_physicsScene { get; private set; }
|
||||
|
||||
static int m_nextLinksetID = 1;
|
||||
public int LinksetID { get; private set; }
|
||||
|
@ -93,13 +93,6 @@ public abstract class BSLinkset
|
|||
// to the physical representation is done via the tainting mechenism.
|
||||
protected object m_linksetActivityLock = new Object();
|
||||
|
||||
// Some linksets have a preferred physical shape.
|
||||
// Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
|
||||
public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
|
||||
{
|
||||
return BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
}
|
||||
|
||||
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
|
||||
public float LinksetMass { get; protected set; }
|
||||
|
||||
|
@ -122,7 +115,7 @@ public abstract class BSLinkset
|
|||
// We create LOTS of linksets.
|
||||
if (m_nextLinksetID <= 0)
|
||||
m_nextLinksetID = 1;
|
||||
PhysicsScene = scene;
|
||||
m_physicsScene = scene;
|
||||
LinksetRoot = parent;
|
||||
m_children = new HashSet<BSPrimLinkable>();
|
||||
LinksetMass = parent.RawMass;
|
||||
|
@ -165,7 +158,7 @@ public abstract class BSLinkset
|
|||
}
|
||||
|
||||
// The child is down to a linkset of just itself
|
||||
return BSLinkset.Factory(PhysicsScene, child);
|
||||
return BSLinkset.Factory(m_physicsScene, child);
|
||||
}
|
||||
|
||||
// Return 'true' if the passed object is the root object of this linkset
|
||||
|
@ -221,7 +214,7 @@ public abstract class BSLinkset
|
|||
// I am the root of a linkset and a new child is being added
|
||||
// Called while LinkActivity is locked.
|
||||
protected abstract void AddChildToLinkset(BSPrimLinkable child);
|
||||
|
||||
|
||||
// I am the root of a linkset and one of my children is being removed.
|
||||
// Safe to call even if the child is not really in my linkset.
|
||||
protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
|
||||
|
@ -263,7 +256,7 @@ public abstract class BSLinkset
|
|||
// This is called when the root body is changing.
|
||||
// Returns 'true' of something was actually removed and would need restoring
|
||||
// Called at taint-time!!
|
||||
public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
|
||||
public abstract bool RemoveDependencies(BSPrimLinkable child);
|
||||
|
||||
// ================================================================
|
||||
protected virtual float ComputeLinksetMass()
|
||||
|
@ -323,8 +316,8 @@ public abstract class BSLinkset
|
|||
// Invoke the detailed logger and output something if it's enabled.
|
||||
protected void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
if (PhysicsScene.PhysicsLogging.Enabled)
|
||||
PhysicsScene.DetailLog(msg, args);
|
||||
if (m_physicsScene.PhysicsLogging.Enabled)
|
||||
m_physicsScene.DetailLog(msg, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ using OMV = OpenMetaverse;
|
|||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
||||
/*
|
||||
// When a child is linked, the relationship position of the child to the parent
|
||||
// is remembered so the child's world position can be recomputed when it is
|
||||
// removed from the linkset.
|
||||
|
@ -88,6 +89,7 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
|
|||
return buff.ToString();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
public sealed class BSLinksetCompound : BSLinkset
|
||||
{
|
||||
|
@ -98,19 +100,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
{
|
||||
}
|
||||
|
||||
// For compound implimented linksets, if there are children, use compound shape for the root.
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
|
||||
{
|
||||
// Returning 'unknown' means we don't have a preference.
|
||||
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
if (IsRoot(requestor) && HasAnyChildren)
|
||||
{
|
||||
ret = BSPhysicsShapeType.SHAPE_COMPOUND;
|
||||
}
|
||||
// DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// When physical properties are changed the linkset needs to recalculate
|
||||
// its internal properties.
|
||||
public override void Refresh(BSPrimLinkable requestor)
|
||||
|
@ -124,14 +113,14 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// Schedule a refresh to happen after all the other taint processing.
|
||||
private void ScheduleRebuild(BSPrimLinkable requestor)
|
||||
{
|
||||
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
|
||||
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
|
||||
requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
|
||||
// When rebuilding, it is possible to set properties that would normally require a rebuild.
|
||||
// If already rebuilding, don't request another rebuild.
|
||||
// If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
|
||||
if (!Rebuilding && HasAnyChildren)
|
||||
{
|
||||
PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
|
||||
m_physicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
|
||||
{
|
||||
if (HasAnyChildren)
|
||||
RecomputeLinksetCompound();
|
||||
|
@ -153,26 +142,11 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
|
||||
ScheduleRebuild(LinksetRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The origional prims are removed from the world as the shape of the root compound
|
||||
// shape takes over.
|
||||
PhysicsScene.PE.AddToCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
PhysicsScene.PE.ForceActivationState(child.PhysBody, ActivationState.DISABLE_SIMULATION);
|
||||
// We don't want collisions from the old linkset children.
|
||||
PhysicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
|
||||
child.PhysBody.collisionType = CollisionType.LinksetChild;
|
||||
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The object is going static (non-physical). Do any setup necessary for a static linkset.
|
||||
// The object is going static (non-physical). We do not do anything for static linksets.
|
||||
// Return 'true' if any properties updated on the passed object.
|
||||
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
||||
// world if it is a static linkset.
|
||||
// Called at taint-time!
|
||||
public override bool MakeStatic(BSPrimLinkable child)
|
||||
{
|
||||
|
@ -180,19 +154,9 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
||||
if (IsRoot(child))
|
||||
{
|
||||
// Schedule a rebuild to verify that the root shape is set to the real shape.
|
||||
ScheduleRebuild(LinksetRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The non-physical children can come back to life.
|
||||
PhysicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
|
||||
child.PhysBody.collisionType = CollisionType.LinksetChild;
|
||||
|
||||
// Don't force activation so setting of DISABLE_SIMULATION can stay if used.
|
||||
PhysicsScene.PE.Activate(child.PhysBody, false);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -200,13 +164,20 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// Called at taint-time.
|
||||
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated)
|
||||
{
|
||||
if (!LinksetRoot.IsPhysicallyActive)
|
||||
{
|
||||
// No reason to do this physical stuff for static linksets.
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,notPhysical", LinksetRoot.LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
// The user moving a child around requires the rebuilding of the linkset compound shape
|
||||
// One problem is this happens when a border is crossed -- the simulator implementation
|
||||
// stores the position into the group which causes the move of the object
|
||||
// but it also means all the child positions get updated.
|
||||
// What would cause an unnecessary rebuild so we make sure the linkset is in a
|
||||
// region before bothering to do a rebuild.
|
||||
if (!IsRoot(updated) && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
|
||||
if (!IsRoot(updated) && m_physicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
|
||||
{
|
||||
// If a child of the linkset is updating only the position or rotation, that can be done
|
||||
// without rebuilding the linkset.
|
||||
|
@ -218,22 +189,22 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// and that is caused by us updating the object.
|
||||
if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
|
||||
{
|
||||
// Find the physical instance of the child
|
||||
if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
|
||||
// Find the physical instance of the child
|
||||
if (LinksetRoot.PhysShape.HasPhysicalShape && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo))
|
||||
{
|
||||
// It is possible that the linkset is still under construction and the child is not yet
|
||||
// inserted into the compound shape. A rebuild of the linkset in a pre-step action will
|
||||
// build the whole thing with the new position or rotation.
|
||||
// The index must be checked because Bullet references the child array but does no validity
|
||||
// checking of the child index passed.
|
||||
int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape);
|
||||
int numLinksetChildren = m_physicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape.physShapeInfo);
|
||||
if (updated.LinksetChildIndex < numLinksetChildren)
|
||||
{
|
||||
BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, updated.LinksetChildIndex);
|
||||
BulletShape linksetChildShape = m_physicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex);
|
||||
if (linksetChildShape.HasPhysicalShape)
|
||||
{
|
||||
// Found the child shape within the compound shape
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, updated.LinksetChildIndex,
|
||||
m_physicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex,
|
||||
updated.RawPosition - LinksetRoot.RawPosition,
|
||||
updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation),
|
||||
true /* shouldRecalculateLocalAabb */);
|
||||
|
@ -275,75 +246,22 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
}
|
||||
|
||||
// Routine called when rebuilding the body of some member of the linkset.
|
||||
// Since we don't keep in world relationships, do nothing unless it's a child changing.
|
||||
// If one of the bodies is being changed, the linkset needs rebuilding.
|
||||
// For instance, a linkset is built and then a mesh asset is read in and the mesh is recreated.
|
||||
// Returns 'true' of something was actually removed and would need restoring
|
||||
// Called at taint-time!!
|
||||
public override bool RemoveBodyDependencies(BSPrimLinkable child)
|
||||
public override bool RemoveDependencies(BSPrimLinkable child)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
|
||||
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child));
|
||||
|
||||
if (!IsRoot(child))
|
||||
{
|
||||
// Because it is a convenient time, recompute child world position and rotation based on
|
||||
// its position in the linkset.
|
||||
RecomputeChildWorldPosition(child, true /* inTaintTime */);
|
||||
child.LinksetInfo = null;
|
||||
}
|
||||
|
||||
// Cannot schedule a refresh/rebuild here because this routine is called when
|
||||
// the linkset is being rebuilt.
|
||||
// InternalRefresh(LinksetRoot);
|
||||
ScheduleRebuild(child);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// When the linkset is built, the child shape is added to the compound shape relative to the
|
||||
// root shape. The linkset then moves around but this does not move the actual child
|
||||
// prim. The child prim's location must be recomputed based on the location of the root shape.
|
||||
private void RecomputeChildWorldPosition(BSPrimLinkable child, bool inTaintTime)
|
||||
{
|
||||
// For the moment (20130201), disable this computation (converting the child physical addr back to
|
||||
// a region address) until we have a good handle on center-of-mass offsets and what the physics
|
||||
// engine moving a child actually means.
|
||||
// The simulator keeps track of where children should be as the linkset moves. Setting
|
||||
// the pos/rot here does not effect that knowledge as there is no good way for the
|
||||
// physics engine to send the simulator an update for a child.
|
||||
|
||||
/*
|
||||
BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;
|
||||
if (lci != null)
|
||||
{
|
||||
if (inTaintTime)
|
||||
{
|
||||
OMV.Vector3 oldPos = child.RawPosition;
|
||||
child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot;
|
||||
child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
|
||||
child.LocalID, oldPos, lci, child.RawPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TaintedObject is not used here so the raw position is set now and not at taint-time.
|
||||
child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot;
|
||||
child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This happens when children have been added to the linkset but the linkset
|
||||
// has not been constructed yet. So like, at taint time, adding children to a linkset
|
||||
// and then changing properties of the children (makePhysical, for instance)
|
||||
// but the post-print action of actually rebuilding the linkset has not yet happened.
|
||||
// PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}",
|
||||
// LogHeader, child.LocalID);
|
||||
DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
|
||||
// Add a new child to the linkset.
|
||||
|
@ -376,7 +294,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
child.LocalID, child.PhysBody.AddrString);
|
||||
|
||||
// Cause the child's body to be rebuilt and thus restored to normal operation
|
||||
RecomputeChildWorldPosition(child, false);
|
||||
child.LinksetInfo = null;
|
||||
child.ForceBodyShapeRebuild(false);
|
||||
|
||||
|
@ -399,108 +316,105 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// Constraint linksets are rebuilt every time.
|
||||
// Note that this works for rebuilding just the root after a linkset is taken apart.
|
||||
// Called at taint time!!
|
||||
private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged
|
||||
private bool UseBulletSimRootOffsetHack = false; // Attempt to have Bullet track the coords of root compound shape
|
||||
private bool disableCOM = true; // For basic linkset debugging, turn off the center-of-mass setting
|
||||
private void RecomputeLinksetCompound()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Suppress rebuilding while rebuilding. (We know rebuilding is on only one thread.)
|
||||
Rebuilding = true;
|
||||
|
||||
// Cause the root shape to be rebuilt as a compound object with just the root in it
|
||||
LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime */);
|
||||
// No matter what is being done, force the root prim's PhysBody and PhysShape to get set
|
||||
// to what they should be as if the root was not in a linkset.
|
||||
// Not that bad since we only get into this routine if there are children in the linkset and
|
||||
// something has been updated/changed.
|
||||
LinksetRoot.ForceBodyShapeRebuild(true);
|
||||
|
||||
// There is no reason to build all this physical stuff for a non-physical linkset.
|
||||
if (!LinksetRoot.IsPhysicallyActive)
|
||||
{
|
||||
// Clean up any old linkset shape and make sure the root shape is set to the root object.
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID);
|
||||
|
||||
return; // Note the 'finally' clause at the botton which will get executed.
|
||||
}
|
||||
|
||||
// Get a new compound shape to build the linkset shape in.
|
||||
BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene);
|
||||
|
||||
// The center of mass for the linkset is the geometric center of the group.
|
||||
// Compute a displacement for each component so it is relative to the center-of-mass.
|
||||
// Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
|
||||
OMV.Vector3 centerOfMassW = LinksetRoot.RawPosition;
|
||||
if (!disableCOM) // DEBUG DEBUG
|
||||
{
|
||||
// Compute a center-of-mass in world coordinates.
|
||||
centerOfMassW = ComputeLinksetCenterOfMass();
|
||||
}
|
||||
OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass();
|
||||
|
||||
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
|
||||
|
||||
// 'centerDisplacement' is the value to subtract from children to give physical offset position
|
||||
OMV.Vector3 centerDisplacement = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
|
||||
LinksetRoot.SetEffectiveCenterOfMassW(centerDisplacement);
|
||||
if (UseBulletSimRootOffsetHack || disableCOM)
|
||||
{
|
||||
centerDisplacement = OMV.Vector3.Zero;
|
||||
LinksetRoot.ClearDisplacement();
|
||||
}
|
||||
else
|
||||
{
|
||||
LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacement);
|
||||
}
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}",
|
||||
LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacement);
|
||||
|
||||
// This causes the physical position of the root prim to be offset to accomodate for the displacements
|
||||
LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
|
||||
|
||||
// Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0 /* childIndex */,
|
||||
-centerDisplacement,
|
||||
OMV.Quaternion.Identity, // LinksetRoot.RawOrientation,
|
||||
false /* shouldRecalculateLocalAabb (is done later after linkset built) */);
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
|
||||
LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement);
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
|
||||
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
|
||||
|
||||
// Add a shape for each of the other children in the linkset
|
||||
// Add the shapes of all the components of the linkset
|
||||
int memberIndex = 1;
|
||||
ForEachMember(delegate(BSPrimLinkable cPrim)
|
||||
{
|
||||
if (IsRoot(cPrim))
|
||||
// Root shape is always index zero.
|
||||
cPrim.LinksetChildIndex = IsRoot(cPrim) ? 0 : memberIndex;
|
||||
|
||||
// Get a reference to the shape of the child and add that shape to the linkset compound shape
|
||||
BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim);
|
||||
OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
|
||||
OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
|
||||
m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot);
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}",
|
||||
LinksetRoot.LocalID, memberIndex, childShape, offsetPos, offsetRot);
|
||||
|
||||
// Since we are borrowing the shape of the child, disable the origional child body
|
||||
if (!IsRoot(cPrim))
|
||||
{
|
||||
cPrim.LinksetChildIndex = 0;
|
||||
m_physicsScene.PE.AddToCollisionFlags(cPrim.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
m_physicsScene.PE.ForceActivationState(cPrim.PhysBody, ActivationState.DISABLE_SIMULATION);
|
||||
// We don't want collisions from the old linkset children.
|
||||
m_physicsScene.PE.RemoveFromCollisionFlags(cPrim.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
cPrim.PhysBody.collisionType = CollisionType.LinksetChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
cPrim.LinksetChildIndex = memberIndex;
|
||||
|
||||
if (cPrim.PhysShape.isNativeShape)
|
||||
{
|
||||
// A native shape is turned into a hull collision shape because native
|
||||
// shapes are not shared so we have to hullify it so it will be tracked
|
||||
// and freed at the correct time. This also solves the scaling problem
|
||||
// (native shapes scale but hull/meshes are assumed to not be).
|
||||
// TODO: decide of the native shape can just be used in the compound shape.
|
||||
// Use call to CreateGeomNonSpecial().
|
||||
BulletShape saveShape = cPrim.PhysShape;
|
||||
cPrim.PhysShape.Clear(); // Don't let the create free the child's shape
|
||||
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
|
||||
BulletShape newShape = cPrim.PhysShape;
|
||||
cPrim.PhysShape = saveShape;
|
||||
memberIndex++;
|
||||
|
||||
OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
|
||||
OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
|
||||
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, offsetPos, offsetRot);
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}",
|
||||
LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, newShape, offsetPos, offsetRot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For the shared shapes (meshes and hulls), just use the shape in the child.
|
||||
// The reference count added here will be decremented when the compound shape
|
||||
// is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
|
||||
if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
|
||||
{
|
||||
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
|
||||
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
|
||||
}
|
||||
OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
|
||||
OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
|
||||
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot);
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNonNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}",
|
||||
LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot);
|
||||
|
||||
}
|
||||
memberIndex++;
|
||||
}
|
||||
return false; // 'false' says to move onto the next child in the list
|
||||
});
|
||||
|
||||
// Replace the root shape with the built compound shape.
|
||||
// Object removed and added to world to get collision cache rebuilt for new shape.
|
||||
LinksetRoot.PhysShape.Dereference(m_physicsScene);
|
||||
LinksetRoot.PhysShape = linksetShape;
|
||||
m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, LinksetRoot.PhysBody);
|
||||
m_physicsScene.PE.SetCollisionShape(m_physicsScene.World, LinksetRoot.PhysBody, linksetShape.physShapeInfo);
|
||||
m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody);
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}",
|
||||
LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape);
|
||||
|
||||
// With all of the linkset packed into the root prim, it has the mass of everyone.
|
||||
LinksetMass = ComputeLinksetMass();
|
||||
LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
|
||||
|
||||
// Enable the physical position updator to return the position and rotation of the root shape
|
||||
PhysicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
|
||||
if (UseBulletSimRootOffsetHack)
|
||||
{
|
||||
// Enable the physical position updator to return the position and rotation of the root shape.
|
||||
// This enables a feature in the C++ code to return the world coordinates of the first shape in the
|
||||
// compound shape. This eleviates the need to offset the returned physical position by the
|
||||
// center-of-mass offset.
|
||||
m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -508,7 +422,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
}
|
||||
|
||||
// See that the Aabb surrounds the new shape
|
||||
PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
|
||||
m_physicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape.physShapeInfo);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
if (HasAnyChildren && IsRoot(requestor))
|
||||
{
|
||||
// Queue to happen after all the other taint processing
|
||||
PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
|
||||
m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
|
||||
{
|
||||
if (HasAnyChildren && IsRoot(requestor))
|
||||
RecomputeLinksetConstraints();
|
||||
|
@ -93,11 +93,11 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
// up to rebuild the constraints before the next simulation step.
|
||||
// Returns 'true' of something was actually removed and would need restoring
|
||||
// Called at taint-time!!
|
||||
public override bool RemoveBodyDependencies(BSPrimLinkable child)
|
||||
public override bool RemoveDependencies(BSPrimLinkable child)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
|
||||
DetailLog("{0},BSLinksetConstraint.RemoveDependencies,removeChildrenForRoot,rID={1},rBody={2}",
|
||||
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString);
|
||||
|
||||
lock (m_linksetActivityLock)
|
||||
|
@ -142,7 +142,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
rootx.LocalID, rootx.PhysBody.AddrString,
|
||||
childx.LocalID, childx.PhysBody.AddrString);
|
||||
|
||||
PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
|
||||
m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
|
||||
{
|
||||
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
||||
});
|
||||
|
@ -187,7 +187,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||
|
||||
BSConstraint6Dof constrain = new BSConstraint6Dof(
|
||||
PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true );
|
||||
m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true );
|
||||
// PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true );
|
||||
|
||||
/* NOTE: below is an attempt to build constraint with full frame computation, etc.
|
||||
|
@ -216,7 +216,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
// ==================================================================================
|
||||
*/
|
||||
|
||||
PhysicsScene.Constraints.AddConstraint(constrain);
|
||||
m_physicsScene.Constraints.AddConstraint(constrain);
|
||||
|
||||
// zero linear and angular limits makes the objects unable to move in relation to each other
|
||||
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||
|
@ -248,10 +248,10 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
childPrim.LocalID, childPrim.PhysBody.AddrString);
|
||||
|
||||
// Find the constraint for this link and get rid of it from the overall collection and from my list
|
||||
if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
|
||||
if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
|
||||
{
|
||||
// Make the child refresh its location
|
||||
PhysicsScene.PE.PushUpdate(childPrim.PhysBody);
|
||||
m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
{
|
||||
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
||||
|
||||
return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody);
|
||||
return m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody);
|
||||
}
|
||||
|
||||
// Call each of the constraints that make up this linkset and recompute the
|
||||
|
@ -289,7 +289,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
child.UpdatePhysicalMassProperties(linksetMass, true);
|
||||
|
||||
BSConstraint constrain;
|
||||
if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
|
||||
if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
|
||||
{
|
||||
// If constraint doesn't exist yet, create it.
|
||||
constrain = BuildConstraint(LinksetRoot, child);
|
||||
|
|
|
@ -102,7 +102,7 @@ public class BSVMotor : BSMotor
|
|||
return ErrorIsZero(LastError);
|
||||
}
|
||||
public virtual bool ErrorIsZero(Vector3 err)
|
||||
{
|
||||
{
|
||||
return (err == Vector3.Zero || err.ApproxEquals(Vector3.Zero, ErrorZeroThreshold));
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ public class BSVMotor : BSMotor
|
|||
CurrentValue = TargetValue = Vector3.Zero;
|
||||
ErrorZeroThreshold = 0.001f;
|
||||
}
|
||||
public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
|
||||
public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
|
||||
: this(useName)
|
||||
{
|
||||
TimeScale = timeScale;
|
||||
|
@ -237,7 +237,7 @@ public class BSVMotor : BSMotor
|
|||
MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName);
|
||||
MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}",
|
||||
BSScene.DetailLogZero, UseName,
|
||||
TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency,
|
||||
TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency,
|
||||
CurrentValue, TargetValue);
|
||||
|
||||
LastError = BSMotor.InfiniteVector;
|
||||
|
@ -248,7 +248,7 @@ public class BSVMotor : BSMotor
|
|||
BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep);
|
||||
}
|
||||
MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ public class BSFMotor : BSMotor
|
|||
return ErrorIsZero(LastError);
|
||||
}
|
||||
public virtual bool ErrorIsZero(float err)
|
||||
{
|
||||
{
|
||||
return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold);
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ public class BSPIDVMotor : BSVMotor
|
|||
// The factors are vectors for the three dimensions. This is the proportional of each
|
||||
// that is applied. This could be multiplied through the actual factors but it
|
||||
// is sometimes easier to manipulate the factors and their mix separately.
|
||||
// to
|
||||
// to
|
||||
public Vector3 FactorMix;
|
||||
|
||||
// Arbritrary factor range.
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
public static class BSParam
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM PARAMETERS]";
|
||||
private static string LogHeader = "[BULLETSIM PARAMETERS]";
|
||||
|
||||
// Tuning notes:
|
||||
// From: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6575
|
||||
|
@ -51,7 +51,7 @@ public static class BSParam
|
|||
// This is separate/independent from the collision margin. The collision margin increases the object a bit
|
||||
// to improve collision detection performance and accuracy.
|
||||
// ===================
|
||||
// From:
|
||||
// From:
|
||||
|
||||
// Level of Detail values kept as float because that's what the Meshmerizer wants
|
||||
public static float MeshLOD { get; private set; }
|
||||
|
@ -87,6 +87,7 @@ public static class BSParam
|
|||
public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
|
||||
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
||||
public static bool ShouldUseBulletHACD { get; set; }
|
||||
public static bool ShouldUseSingleConvexHullForPrims { get; set; }
|
||||
|
||||
public static float TerrainImplementation { get; private set; }
|
||||
public static int TerrainMeshMagnification { get; private set; }
|
||||
|
@ -342,6 +343,10 @@ public static class BSParam
|
|||
false,
|
||||
(s) => { return ShouldUseBulletHACD; },
|
||||
(s,v) => { ShouldUseBulletHACD = v; } ),
|
||||
new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
|
||||
true,
|
||||
(s) => { return ShouldUseSingleConvexHullForPrims; },
|
||||
(s,v) => { ShouldUseSingleConvexHullForPrims = v; } ),
|
||||
|
||||
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
||||
5,
|
||||
|
@ -636,7 +641,7 @@ public static class BSParam
|
|||
new ParameterDefn<bool>("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
|
||||
false,
|
||||
(s) => { return ShouldDisableContactPoolDynamicAllocation; },
|
||||
(s,v) => { ShouldDisableContactPoolDynamicAllocation = v;
|
||||
(s,v) => { ShouldDisableContactPoolDynamicAllocation = v;
|
||||
s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ),
|
||||
new ParameterDefn<bool>("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
|
||||
false,
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
* Class to wrap all objects.
|
||||
* The rest of BulletSim doesn't need to keep checking for avatars or prims
|
||||
* unless the difference is significant.
|
||||
*
|
||||
*
|
||||
* Variables in the physicsl objects are in three forms:
|
||||
* VariableName: used by the simulator and performs taint operations, etc
|
||||
* RawVariableName: direct reference to the BulletSim storage for the variable value
|
||||
|
@ -52,7 +52,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
* SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce
|
||||
* SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse
|
||||
* PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v
|
||||
* BS.ApplyCentralForce BS.ApplyTorque
|
||||
* BS.ApplyCentralForce BS.ApplyTorque
|
||||
*/
|
||||
|
||||
// Flags used to denote which properties updates when making UpdateProperties calls to linksets, etc.
|
||||
|
@ -72,14 +72,14 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
}
|
||||
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
|
||||
{
|
||||
PhysicsScene = parentScene;
|
||||
PhysScene = parentScene;
|
||||
LocalID = localID;
|
||||
PhysObjectName = name;
|
||||
Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
|
||||
TypeName = typeName;
|
||||
|
||||
// The collection of things that push me around
|
||||
PhysicalActors = new BSActorCollection(PhysicsScene);
|
||||
PhysicalActors = new BSActorCollection(PhysScene);
|
||||
|
||||
// Initialize variables kept in base.
|
||||
GravModifier = 1.0f;
|
||||
|
@ -88,7 +88,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
// We don't have any physical representation yet.
|
||||
PhysBody = new BulletBody(localID);
|
||||
PhysShape = new BulletShape();
|
||||
PhysShape = new BSShapeNull();
|
||||
|
||||
PrimAssetState = PrimAssetCondition.Unknown;
|
||||
|
||||
|
@ -115,13 +115,13 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public virtual void Destroy()
|
||||
{
|
||||
PhysicalActors.Enable(false);
|
||||
PhysicsScene.TaintedObject("BSPhysObject.Destroy", delegate()
|
||||
PhysScene.TaintedObject("BSPhysObject.Destroy", delegate()
|
||||
{
|
||||
PhysicalActors.Dispose();
|
||||
});
|
||||
}
|
||||
|
||||
public BSScene PhysicsScene { get; protected set; }
|
||||
public BSScene PhysScene { get; protected set; }
|
||||
// public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor
|
||||
public string PhysObjectName { get; protected set; }
|
||||
public string TypeName { get; protected set; }
|
||||
|
@ -141,7 +141,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// Reference to the physical body (btCollisionObject) of this object
|
||||
public BulletBody PhysBody;
|
||||
// Reference to the physical shape (btCollisionShape) of this object
|
||||
public BulletShape PhysShape;
|
||||
public BSShape PhysShape;
|
||||
|
||||
// The physical representation of the prim might require an asset fetch.
|
||||
// The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'.
|
||||
|
@ -154,13 +154,6 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// The objects base shape information. Null if not a prim type shape.
|
||||
public PrimitiveBaseShape BaseShape { get; protected set; }
|
||||
|
||||
// Some types of objects have preferred physical representations.
|
||||
// Returns SHAPE_UNKNOWN if there is no preference.
|
||||
public virtual BSPhysicsShapeType PreferredPhysicalShape
|
||||
{
|
||||
get { return BSPhysicsShapeType.SHAPE_UNKNOWN; }
|
||||
}
|
||||
|
||||
// When the physical properties are updated, an EntityProperty holds the update values.
|
||||
// Keep the current and last EntityProperties to enable computation of differences
|
||||
// between the current update and the previous values.
|
||||
|
@ -269,7 +262,8 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
// The user can optionally set the center of mass. The user's setting will override any
|
||||
// computed center-of-mass (like in linksets).
|
||||
public OMV.Vector3? UserSetCenterOfMass { get; set; }
|
||||
// Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass.
|
||||
public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; }
|
||||
|
||||
public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
|
||||
public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free
|
||||
|
@ -280,7 +274,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public void ActivateIfPhysical(bool forceIt)
|
||||
{
|
||||
if (IsPhysical && PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.Activate(PhysBody, forceIt);
|
||||
PhysScene.PE.Activate(PhysBody, forceIt);
|
||||
}
|
||||
|
||||
// 'actors' act on the physical object to change or constrain its motion. These can range from
|
||||
|
@ -343,29 +337,29 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
protected long CollisionAccumulation { get; set; }
|
||||
|
||||
public override bool IsColliding {
|
||||
get { return (CollidingStep == PhysicsScene.SimulationStep); }
|
||||
get { return (CollidingStep == PhysScene.SimulationStep); }
|
||||
set {
|
||||
if (value)
|
||||
CollidingStep = PhysicsScene.SimulationStep;
|
||||
CollidingStep = PhysScene.SimulationStep;
|
||||
else
|
||||
CollidingStep = 0;
|
||||
}
|
||||
}
|
||||
public override bool CollidingGround {
|
||||
get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
|
||||
get { return (CollidingGroundStep == PhysScene.SimulationStep); }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
CollidingGroundStep = PhysicsScene.SimulationStep;
|
||||
CollidingGroundStep = PhysScene.SimulationStep;
|
||||
else
|
||||
CollidingGroundStep = 0;
|
||||
}
|
||||
}
|
||||
public override bool CollidingObj {
|
||||
get { return (CollidingObjectStep == PhysicsScene.SimulationStep); }
|
||||
set {
|
||||
get { return (CollidingObjectStep == PhysScene.SimulationStep); }
|
||||
set {
|
||||
if (value)
|
||||
CollidingObjectStep = PhysicsScene.SimulationStep;
|
||||
CollidingObjectStep = PhysScene.SimulationStep;
|
||||
else
|
||||
CollidingObjectStep = 0;
|
||||
}
|
||||
|
@ -390,14 +384,14 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
bool ret = false;
|
||||
|
||||
// The following lines make IsColliding(), CollidingGround() and CollidingObj work
|
||||
CollidingStep = PhysicsScene.SimulationStep;
|
||||
if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
|
||||
CollidingStep = PhysScene.SimulationStep;
|
||||
if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID)
|
||||
{
|
||||
CollidingGroundStep = PhysicsScene.SimulationStep;
|
||||
CollidingGroundStep = PhysScene.SimulationStep;
|
||||
}
|
||||
else
|
||||
{
|
||||
CollidingObjectStep = PhysicsScene.SimulationStep;
|
||||
CollidingObjectStep = PhysScene.SimulationStep;
|
||||
}
|
||||
|
||||
CollisionAccumulation++;
|
||||
|
@ -407,10 +401,10 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
// Make a collection of the collisions that happened the last simulation tick.
|
||||
// This is different than the collection created for sending up to the simulator as it is cleared every tick.
|
||||
if (CollisionsLastTickStep != PhysicsScene.SimulationStep)
|
||||
if (CollisionsLastTickStep != PhysScene.SimulationStep)
|
||||
{
|
||||
CollisionsLastTick = new CollisionEventUpdate();
|
||||
CollisionsLastTickStep = PhysicsScene.SimulationStep;
|
||||
CollisionsLastTickStep = PhysScene.SimulationStep;
|
||||
}
|
||||
CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
|
||||
|
@ -437,9 +431,9 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
bool force = (CollisionCollection.Count == 0 && CollisionsLastReported.Count != 0);
|
||||
|
||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||
if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
|
||||
if (force || (PhysScene.SimulationNowTime >= NextCollisionOkTime))
|
||||
{
|
||||
NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs;
|
||||
NextCollisionOkTime = PhysScene.SimulationNowTime + SubscribedEventsMs;
|
||||
|
||||
// We are called if we previously had collisions. If there are no collisions
|
||||
// this time, send up one last empty event so OpenSim can sense collision end.
|
||||
|
@ -457,7 +451,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
// The CollisionCollection instance is passed around in the simulator.
|
||||
// Make sure we don't have a handle to that one and that a new one is used for next time.
|
||||
// This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
|
||||
// This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
|
||||
// a race condition is created for the other users of this instance.
|
||||
CollisionCollection = new CollisionEventUpdate();
|
||||
}
|
||||
|
@ -474,10 +468,10 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// make sure first collision happens
|
||||
NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
|
||||
|
||||
PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
|
||||
PhysScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
@ -489,11 +483,11 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public override void UnSubscribeEvents() {
|
||||
// DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
|
||||
SubscribedEventsMs = 0;
|
||||
PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
|
||||
PhysScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
|
||||
{
|
||||
// Make sure there is a body there because sometimes destruction happens in an un-ideal order.
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
}
|
||||
// Return 'true' if the simulator wants collision events
|
||||
|
@ -507,7 +501,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
{
|
||||
// Scale the collision count by the time since the last collision.
|
||||
// The "+1" prevents dividing by zero.
|
||||
long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1;
|
||||
long timeAgo = PhysScene.SimulationStep - CollidingStep + 1;
|
||||
CollisionScore = CollisionAccumulation / timeAgo;
|
||||
}
|
||||
public override float CollisionScore { get; set; }
|
||||
|
@ -534,8 +528,8 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// High performance detailed logging routine used by the physical objects.
|
||||
protected void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
if (PhysicsScene.PhysicsLogging.Enabled)
|
||||
PhysicsScene.DetailLog(msg, args);
|
||||
if (PhysScene.PhysicsLogging.Enabled)
|
||||
PhysScene.DetailLog(msg, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -101,21 +101,21 @@ public class BSPrim : BSPhysObject
|
|||
_isVolumeDetect = false;
|
||||
|
||||
// We keep a handle to the vehicle actor so we can set vehicle parameters later.
|
||||
VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName);
|
||||
VehicleActor = new BSDynamics(PhysScene, this, VehicleActorName);
|
||||
PhysicalActors.Add(VehicleActorName, VehicleActor);
|
||||
|
||||
_mass = CalculateMass();
|
||||
|
||||
// DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||
// do the actual object creation at taint time
|
||||
PhysicsScene.TaintedObject("BSPrim.create", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.create", delegate()
|
||||
{
|
||||
// Make sure the object is being created with some sanity.
|
||||
ExtremeSanityCheck(true /* inTaintTime */);
|
||||
|
||||
CreateGeomAndObject(true);
|
||||
|
||||
CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody);
|
||||
CurrentCollisionFlags = PhysScene.PE.GetCollisionFlags(PhysBody);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -128,14 +128,14 @@ public class BSPrim : BSPhysObject
|
|||
// Undo any vehicle properties
|
||||
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||
|
||||
PhysicsScene.TaintedObject("BSPrim.Destroy", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.Destroy", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||
// If there are physical body and shape, release my use of same.
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, null);
|
||||
PhysScene.Shapes.DereferenceBody(PhysBody, null);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, null);
|
||||
PhysShape.Clear();
|
||||
PhysShape.Dereference(PhysScene);
|
||||
PhysShape = new BSShapeNull();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -161,25 +161,13 @@ public class BSPrim : BSPhysObject
|
|||
ForceBodyShapeRebuild(false);
|
||||
}
|
||||
}
|
||||
// 'unknown' says to choose the best type
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||
{ get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } }
|
||||
|
||||
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
||||
{
|
||||
if (inTaintTime)
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
CreateGeomAndObject(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
CreateGeomAndObject(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
public override bool Grabbed {
|
||||
|
@ -192,7 +180,7 @@ public class BSPrim : BSPhysObject
|
|||
if (value != _isSelected)
|
||||
{
|
||||
_isSelected = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setSelected", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
|
||||
SetObjectDynamic(false);
|
||||
|
@ -238,23 +226,23 @@ public class BSPrim : BSPhysObject
|
|||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
|
||||
// Zero some other properties in the physics engine
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.ClearAllForces(PhysBody);
|
||||
PhysScene.PE.ClearAllForces(PhysBody);
|
||||
});
|
||||
}
|
||||
public override void ZeroAngularMotion(bool inTaintTime)
|
||||
{
|
||||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
// Zero some other properties in the physics engine
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
|
||||
{
|
||||
// DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -272,11 +260,11 @@ public class BSPrim : BSPhysObject
|
|||
|
||||
EnableActor(LockedAxis != LockedAxisFree, LockedAxisActorName, delegate()
|
||||
{
|
||||
return new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName);
|
||||
return new BSActorLockAxis(PhysScene, this, LockedAxisActorName);
|
||||
});
|
||||
|
||||
// Update parameters so the new actor's Refresh() action is called at the right time.
|
||||
PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
|
||||
{
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
|
@ -306,7 +294,7 @@ public class BSPrim : BSPhysObject
|
|||
_position = value;
|
||||
PositionSanityCheck(false);
|
||||
|
||||
PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setPosition", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
ForcePosition = _position;
|
||||
|
@ -316,14 +304,14 @@ public class BSPrim : BSPhysObject
|
|||
|
||||
public override OMV.Vector3 ForcePosition {
|
||||
get {
|
||||
_position = PhysicsScene.PE.GetPosition(PhysBody);
|
||||
_position = PhysScene.PE.GetPosition(PhysBody);
|
||||
return _position;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +328,7 @@ public class BSPrim : BSPhysObject
|
|||
if (!IsPhysicallyActive)
|
||||
return ret;
|
||||
|
||||
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||
if (!PhysScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||
{
|
||||
// The physical object is out of the known/simulated area.
|
||||
// Upper levels of code will handle the transition to other areas so, for
|
||||
|
@ -348,7 +336,7 @@ public class BSPrim : BSPhysObject
|
|||
return ret;
|
||||
}
|
||||
|
||||
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
|
||||
float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
|
||||
OMV.Vector3 upForce = OMV.Vector3.Zero;
|
||||
float approxSize = Math.Max(Size.X, Math.Max(Size.Y, Size.Z));
|
||||
if ((RawPosition.Z + approxSize / 2f) < terrainHeight)
|
||||
|
@ -369,7 +357,7 @@ public class BSPrim : BSPhysObject
|
|||
|
||||
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
||||
{
|
||||
float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||
// TODO: a floating motor so object will bob in the water
|
||||
if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
|
||||
{
|
||||
|
@ -377,7 +365,7 @@ public class BSPrim : BSPhysObject
|
|||
upForce.Z = (waterHeight - RawPosition.Z) * 1f;
|
||||
|
||||
// Apply upforce and overcome gravity.
|
||||
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
|
||||
OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity;
|
||||
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
|
||||
AddForce(correctionForce, false, inTaintTime);
|
||||
ret = true;
|
||||
|
@ -432,7 +420,7 @@ public class BSPrim : BSPhysObject
|
|||
get { return _mass; }
|
||||
}
|
||||
// used when we only want this prim's mass and not the linkset thing
|
||||
public override float RawMass {
|
||||
public override float RawMass {
|
||||
get { return _mass; }
|
||||
}
|
||||
// Set the physical mass to the passed mass.
|
||||
|
@ -443,10 +431,10 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
PhysicsScene.PE.SetGravity(PhysBody, PhysicsScene.DefaultGravity);
|
||||
PhysScene.PE.SetGravity(PhysBody, PhysScene.DefaultGravity);
|
||||
Inertia = OMV.Vector3.Zero;
|
||||
PhysicsScene.PE.SetMassProps(PhysBody, 0f, Inertia);
|
||||
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
|
||||
PhysScene.PE.SetMassProps(PhysBody, 0f, Inertia);
|
||||
PhysScene.PE.UpdateInertiaTensor(PhysBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -455,16 +443,16 @@ public class BSPrim : BSPhysObject
|
|||
// Changing interesting properties doesn't change proxy and collision cache
|
||||
// information. The Bullet solution is to re-add the object to the world
|
||||
// after parameters are changed.
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
|
||||
}
|
||||
|
||||
// The computation of mass props requires gravity to be set on the object.
|
||||
Gravity = ComputeGravity(Buoyancy);
|
||||
PhysicsScene.PE.SetGravity(PhysBody, Gravity);
|
||||
PhysScene.PE.SetGravity(PhysBody, Gravity);
|
||||
|
||||
Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
|
||||
PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia);
|
||||
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
|
||||
Inertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
|
||||
PhysScene.PE.SetMassProps(PhysBody, physMass, Inertia);
|
||||
PhysScene.PE.UpdateInertiaTensor(PhysBody);
|
||||
|
||||
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}",
|
||||
LocalID, physMass, Inertia, Gravity, inWorld);
|
||||
|
@ -480,7 +468,7 @@ public class BSPrim : BSPhysObject
|
|||
// Return what gravity should be set to this very moment
|
||||
public OMV.Vector3 ComputeGravity(float buoyancy)
|
||||
{
|
||||
OMV.Vector3 ret = PhysicsScene.DefaultGravity;
|
||||
OMV.Vector3 ret = PhysScene.DefaultGravity;
|
||||
|
||||
if (!IsStatic)
|
||||
{
|
||||
|
@ -509,7 +497,7 @@ public class BSPrim : BSPhysObject
|
|||
RawForce = value;
|
||||
EnableActor(RawForce != OMV.Vector3.Zero, SetForceActorName, delegate()
|
||||
{
|
||||
return new BSActorSetForce(PhysicsScene, this, SetForceActorName);
|
||||
return new BSActorSetForce(PhysScene, this, SetForceActorName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -521,9 +509,9 @@ public class BSPrim : BSPhysObject
|
|||
set {
|
||||
Vehicle type = (Vehicle)value;
|
||||
|
||||
PhysicsScene.TaintedObject("setVehicleType", delegate()
|
||||
PhysScene.TaintedObject("setVehicleType", delegate()
|
||||
{
|
||||
// Vehicle code changes the parameters for this vehicle type.
|
||||
ZeroMotion(true /* inTaintTime */);
|
||||
VehicleActor.ProcessTypeChange(type);
|
||||
ActivateIfPhysical(false);
|
||||
});
|
||||
|
@ -531,7 +519,7 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
public override void VehicleFloatParam(int param, float value)
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||
{
|
||||
VehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
|
@ -539,7 +527,7 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||
{
|
||||
VehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
|
@ -547,7 +535,7 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||
{
|
||||
VehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
ActivateIfPhysical(false);
|
||||
|
@ -555,7 +543,7 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
public override void VehicleFlags(int param, bool remove)
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||
{
|
||||
VehicleActor.ProcessVehicleFlags(param, remove);
|
||||
});
|
||||
|
@ -567,7 +555,7 @@ public class BSPrim : BSPhysObject
|
|||
if (_isVolumeDetect != newValue)
|
||||
{
|
||||
_isVolumeDetect = newValue;
|
||||
PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
|
||||
{
|
||||
// DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
|
||||
SetObjectDynamic(true);
|
||||
|
@ -578,7 +566,7 @@ public class BSPrim : BSPhysObject
|
|||
public override void SetMaterial(int material)
|
||||
{
|
||||
base.SetMaterial(material);
|
||||
PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.SetMaterial", delegate()
|
||||
{
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
|
@ -591,7 +579,7 @@ public class BSPrim : BSPhysObject
|
|||
if (base.Friction != value)
|
||||
{
|
||||
base.Friction = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setFriction", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setFriction", delegate()
|
||||
{
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
|
@ -606,7 +594,7 @@ public class BSPrim : BSPhysObject
|
|||
if (base.Restitution != value)
|
||||
{
|
||||
base.Restitution = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setRestitution", delegate()
|
||||
{
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
|
@ -623,7 +611,7 @@ public class BSPrim : BSPhysObject
|
|||
if (base.Density != value)
|
||||
{
|
||||
base.Density = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setDensity", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setDensity", delegate()
|
||||
{
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
|
@ -638,7 +626,7 @@ public class BSPrim : BSPhysObject
|
|||
if (base.GravModifier != value)
|
||||
{
|
||||
base.GravModifier = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setGravityModifier", delegate()
|
||||
{
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
|
@ -649,7 +637,7 @@ public class BSPrim : BSPhysObject
|
|||
get { return RawVelocity; }
|
||||
set {
|
||||
RawVelocity = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||
{
|
||||
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
|
||||
ForceVelocity = RawVelocity;
|
||||
|
@ -659,13 +647,13 @@ public class BSPrim : BSPhysObject
|
|||
public override OMV.Vector3 ForceVelocity {
|
||||
get { return RawVelocity; }
|
||||
set {
|
||||
PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity");
|
||||
PhysScene.AssertInTaintTime("BSPrim.ForceVelocity");
|
||||
|
||||
RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, RawVelocity);
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
|
||||
PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
}
|
||||
|
@ -676,7 +664,7 @@ public class BSPrim : BSPhysObject
|
|||
RawTorque = value;
|
||||
EnableActor(RawTorque != OMV.Vector3.Zero, SetTorqueActorName, delegate()
|
||||
{
|
||||
return new BSActorSetTorque(PhysicsScene, this, SetTorqueActorName);
|
||||
return new BSActorSetTorque(PhysScene, this, SetTorqueActorName);
|
||||
});
|
||||
DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
|
||||
}
|
||||
|
@ -699,7 +687,7 @@ public class BSPrim : BSPhysObject
|
|||
return;
|
||||
_orientation = value;
|
||||
|
||||
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||
{
|
||||
ForceOrientation = _orientation;
|
||||
});
|
||||
|
@ -710,14 +698,14 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
get
|
||||
{
|
||||
_orientation = PhysicsScene.PE.GetOrientation(PhysBody);
|
||||
_orientation = PhysScene.PE.GetOrientation(PhysBody);
|
||||
return _orientation;
|
||||
}
|
||||
set
|
||||
{
|
||||
_orientation = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
}
|
||||
}
|
||||
public override int PhysicsActorType {
|
||||
|
@ -730,7 +718,7 @@ public class BSPrim : BSPhysObject
|
|||
if (_isPhysical != value)
|
||||
{
|
||||
_isPhysical = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
||||
{
|
||||
DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
|
||||
SetObjectDynamic(true);
|
||||
|
@ -779,13 +767,13 @@ public class BSPrim : BSPhysObject
|
|||
if (!PhysBody.HasPhysicalBody)
|
||||
{
|
||||
// This would only happen if updates are called for during initialization when the body is not set up yet.
|
||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID);
|
||||
// DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mangling all the physical properties requires the object not be in the physical world.
|
||||
// This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
|
||||
|
||||
// Set up the object physicalness (does gravity and collisions move this object)
|
||||
MakeDynamic(IsStatic);
|
||||
|
@ -802,10 +790,11 @@ public class BSPrim : BSPhysObject
|
|||
AddObjectToPhysicalWorld();
|
||||
|
||||
// Rebuild its shape
|
||||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody);
|
||||
|
||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
|
||||
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
||||
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(),
|
||||
CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
||||
}
|
||||
|
||||
// "Making dynamic" means changing to and from static.
|
||||
|
@ -818,28 +807,28 @@ public class BSPrim : BSPhysObject
|
|||
if (makeStatic)
|
||||
{
|
||||
// Become a Bullet 'static' object type
|
||||
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
// Stop all movement
|
||||
ZeroMotion(true);
|
||||
|
||||
// Set various physical properties so other object interact properly
|
||||
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||
PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
PhysScene.PE.SetFriction(PhysBody, Friction);
|
||||
PhysScene.PE.SetRestitution(PhysBody, Restitution);
|
||||
PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
|
||||
// Mass is zero which disables a bunch of physics stuff in Bullet
|
||||
UpdatePhysicalMassProperties(0f, false);
|
||||
// Set collision detection parameters
|
||||
if (BSParam.CcdMotionThreshold > 0f)
|
||||
{
|
||||
PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
|
||||
PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
|
||||
PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
|
||||
PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
|
||||
}
|
||||
|
||||
// The activation state is 'disabled' so Bullet will not try to act on it.
|
||||
// PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_SIMULATION);
|
||||
// Start it out sleeping and physical actions could wake it up.
|
||||
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ISLAND_SLEEPING);
|
||||
PhysScene.PE.ForceActivationState(PhysBody, ActivationState.ISLAND_SLEEPING);
|
||||
|
||||
// This collides like a static object
|
||||
PhysBody.collisionType = CollisionType.Static;
|
||||
|
@ -847,11 +836,11 @@ public class BSPrim : BSPhysObject
|
|||
else
|
||||
{
|
||||
// Not a Bullet static object
|
||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
|
||||
// Set various physical properties so other object interact properly
|
||||
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||
PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
|
||||
PhysScene.PE.SetFriction(PhysBody, Friction);
|
||||
PhysScene.PE.SetRestitution(PhysBody, Restitution);
|
||||
// DetailLog("{0},BSPrim.MakeDynamic,frict={1},rest={2}", LocalID, Friction, Restitution);
|
||||
|
||||
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
|
||||
|
@ -869,22 +858,22 @@ public class BSPrim : BSPhysObject
|
|||
// Set collision detection parameters
|
||||
if (BSParam.CcdMotionThreshold > 0f)
|
||||
{
|
||||
PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
|
||||
PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
|
||||
PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
|
||||
PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
|
||||
}
|
||||
|
||||
// Various values for simulation limits
|
||||
PhysicsScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping);
|
||||
PhysicsScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime);
|
||||
PhysicsScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
PhysScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping);
|
||||
PhysScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime);
|
||||
PhysScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
|
||||
PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
|
||||
// This collides like an object.
|
||||
PhysBody.collisionType = CollisionType.Dynamic;
|
||||
|
||||
// Force activation of the object so Bullet will act on it.
|
||||
// Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
|
||||
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
|
||||
PhysScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,7 +883,7 @@ public class BSPrim : BSPhysObject
|
|||
// the functions after this one set up the state of a possibly newly created collision body.
|
||||
private void MakeSolid(bool makeSolid)
|
||||
{
|
||||
CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(PhysBody);
|
||||
CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysScene.PE.GetBodyType(PhysBody);
|
||||
if (makeSolid)
|
||||
{
|
||||
// Verify the previous code created the correct shape for this type of thing.
|
||||
|
@ -902,7 +891,7 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType);
|
||||
}
|
||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -910,7 +899,7 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
|
||||
}
|
||||
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
|
||||
// Change collision info from a static object to a ghosty collision object
|
||||
PhysBody.collisionType = CollisionType.VolumeDetect;
|
||||
|
@ -922,11 +911,11 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
if (wantsCollisionEvents)
|
||||
{
|
||||
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,7 +926,7 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
|
||||
PhysScene.PE.AddObjectToWorld(PhysScene.World, PhysBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -972,12 +961,12 @@ public class BSPrim : BSPhysObject
|
|||
public override bool FloatOnWater {
|
||||
set {
|
||||
_floatOnWater = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
|
||||
{
|
||||
if (_floatOnWater)
|
||||
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
else
|
||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -989,7 +978,7 @@ public class BSPrim : BSPhysObject
|
|||
_rotationalVelocity = value;
|
||||
Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
|
||||
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
|
||||
PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||
{
|
||||
ForceRotationalVelocity = _rotationalVelocity;
|
||||
});
|
||||
|
@ -1004,7 +993,7 @@ public class BSPrim : BSPhysObject
|
|||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||
PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
// PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
|
@ -1020,7 +1009,7 @@ public class BSPrim : BSPhysObject
|
|||
get { return _buoyancy; }
|
||||
set {
|
||||
_buoyancy = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||
PhysScene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||
{
|
||||
ForceBuoyancy = _buoyancy;
|
||||
});
|
||||
|
@ -1043,7 +1032,7 @@ public class BSPrim : BSPhysObject
|
|||
base.MoveToTargetActive = value;
|
||||
EnableActor(MoveToTargetActive, MoveToTargetActorName, delegate()
|
||||
{
|
||||
return new BSActorMoveToTarget(PhysicsScene, this, MoveToTargetActorName);
|
||||
return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1055,7 +1044,7 @@ public class BSPrim : BSPhysObject
|
|||
base.HoverActive = value;
|
||||
EnableActor(HoverActive, HoverActorName, delegate()
|
||||
{
|
||||
return new BSActorHover(PhysicsScene, this, HoverActorName);
|
||||
return new BSActorHover(PhysScene, this, HoverActorName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1065,7 +1054,7 @@ public class BSPrim : BSPhysObject
|
|||
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
|
||||
|
||||
// Since this force is being applied in only one step, make this a force per second.
|
||||
addForce /= PhysicsScene.LastTimeStep;
|
||||
addForce /= PhysScene.LastTimeStep;
|
||||
AddForce(addForce, pushforce, false /* inTaintTime */);
|
||||
}
|
||||
|
||||
|
@ -1080,13 +1069,13 @@ public class BSPrim : BSPhysObject
|
|||
// DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
|
||||
|
||||
OMV.Vector3 addForce = force;
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
|
||||
{
|
||||
// Bullet adds this central force to the total force for this tick
|
||||
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
|
||||
PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
|
@ -1108,13 +1097,13 @@ public class BSPrim : BSPhysObject
|
|||
OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude);
|
||||
// DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate()
|
||||
{
|
||||
// Bullet adds this impulse immediately to the velocity
|
||||
DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse);
|
||||
PhysScene.PE.ApplyCentralImpulse(PhysBody, addImpulse);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
|
@ -1133,12 +1122,12 @@ public class BSPrim : BSPhysObject
|
|||
if (force.IsFinite())
|
||||
{
|
||||
OMV.Vector3 angForce = force;
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
DetailLog("{0},BSPrim.AddAngularForce,taint,angForce={1}", LocalID, angForce);
|
||||
PhysicsScene.PE.ApplyTorque(PhysBody, angForce);
|
||||
PhysScene.PE.ApplyTorque(PhysBody, angForce);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
|
@ -1157,11 +1146,11 @@ public class BSPrim : BSPhysObject
|
|||
public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
|
||||
{
|
||||
OMV.Vector3 applyImpulse = impulse;
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse);
|
||||
PhysScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
|
@ -1463,12 +1452,13 @@ public class BSPrim : BSPhysObject
|
|||
// Create the correct physical representation for this type of object.
|
||||
// Updates base.PhysBody and base.PhysShape with the new information.
|
||||
// Ignore 'forceRebuild'. 'GetBodyAndShape' makes the right choices and changes of necessary.
|
||||
PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, null, delegate(BulletBody dBody)
|
||||
PhysScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysScene.World, this, delegate(BulletBody pBody, BulletShape pShape)
|
||||
{
|
||||
// Called if the current prim body is about to be destroyed.
|
||||
// Remove all the physical dependencies on the old body.
|
||||
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
||||
RemoveBodyDependencies();
|
||||
// Note: this virtual function is overloaded by BSPrimLinkable to remove linkset constraints.
|
||||
RemoveDependencies();
|
||||
});
|
||||
|
||||
// Make sure the properties are set on the new object
|
||||
|
@ -1477,9 +1467,9 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
|
||||
// Called at taint-time
|
||||
protected virtual void RemoveBodyDependencies()
|
||||
protected virtual void RemoveDependencies()
|
||||
{
|
||||
PhysicalActors.RemoveBodyDependencies();
|
||||
PhysicalActors.RemoveDependencies();
|
||||
}
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
|
|
|
@ -78,14 +78,16 @@ public class BSPrimDisplaced : BSPrim
|
|||
// Set this sets and computes the displacement from the passed prim to the center-of-mass.
|
||||
// A user set value for center-of-mass overrides whatever might be passed in here.
|
||||
// The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
|
||||
public virtual void SetEffectiveCenterOfMassW(Vector3 centerOfMassDisplacement)
|
||||
public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
|
||||
{
|
||||
Vector3 comDisp;
|
||||
if (UserSetCenterOfMass.HasValue)
|
||||
comDisp = (OMV.Vector3)UserSetCenterOfMass;
|
||||
if (UserSetCenterOfMassDisplacement.HasValue)
|
||||
comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
|
||||
else
|
||||
comDisp = centerOfMassDisplacement;
|
||||
|
||||
DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}",
|
||||
LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp);
|
||||
if (comDisp == Vector3.Zero)
|
||||
{
|
||||
// If there is no diplacement. Things get reset.
|
||||
|
@ -107,9 +109,15 @@ public class BSPrimDisplaced : BSPrim
|
|||
set
|
||||
{
|
||||
if (PositionDisplacement != OMV.Vector3.Zero)
|
||||
base.ForcePosition = value - (PositionDisplacement * RawOrientation);
|
||||
{
|
||||
OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation);
|
||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos);
|
||||
base.ForcePosition = displacedPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ForcePosition = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,6 +126,7 @@ public class BSPrimDisplaced : BSPrim
|
|||
get { return base.ForceOrientation; }
|
||||
set
|
||||
{
|
||||
// TODO:
|
||||
base.ForceOrientation = value;
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +152,10 @@ public class BSPrimDisplaced : BSPrim
|
|||
{
|
||||
// Correct for any rotation around the center-of-mass
|
||||
// TODO!!!
|
||||
entprop.Position = entprop.Position + (PositionDisplacement * entprop.Rotation);
|
||||
|
||||
OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation);
|
||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos);
|
||||
entprop.Position = displacedPos;
|
||||
// entprop.Rotation = something;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,9 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||
: base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
|
||||
{
|
||||
Linkset = BSLinkset.Factory(PhysicsScene, this);
|
||||
Linkset = BSLinkset.Factory(PhysScene, this);
|
||||
|
||||
PhysicsScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
|
||||
PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
|
||||
{
|
||||
Linkset.Refresh(this);
|
||||
});
|
||||
|
@ -61,9 +61,6 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
base.Destroy();
|
||||
}
|
||||
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||
{ get { return Linkset.PreferredPhysicalShape(this); } }
|
||||
|
||||
public override void link(Manager.PhysicsActor obj)
|
||||
{
|
||||
BSPrimLinkable parent = obj as BSPrimLinkable;
|
||||
|
@ -102,7 +99,7 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
set
|
||||
{
|
||||
base.Position = value;
|
||||
PhysicsScene.TaintedObject("BSPrimLinkset.setPosition", delegate()
|
||||
PhysScene.TaintedObject("BSPrimLinkset.setPosition", delegate()
|
||||
{
|
||||
Linkset.UpdateProperties(UpdatedProperties.Position, this);
|
||||
});
|
||||
|
@ -116,7 +113,7 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
set
|
||||
{
|
||||
base.Orientation = value;
|
||||
PhysicsScene.TaintedObject("BSPrimLinkset.setOrientation", delegate()
|
||||
PhysScene.TaintedObject("BSPrimLinkset.setOrientation", delegate()
|
||||
{
|
||||
Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
|
||||
});
|
||||
|
@ -149,10 +146,10 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
}
|
||||
|
||||
// Body is being taken apart. Remove physical dependencies and schedule a rebuild.
|
||||
protected override void RemoveBodyDependencies()
|
||||
protected override void RemoveDependencies()
|
||||
{
|
||||
Linkset.RemoveBodyDependencies(this);
|
||||
base.RemoveBodyDependencies();
|
||||
Linkset.RemoveDependencies(this);
|
||||
base.RemoveDependencies();
|
||||
}
|
||||
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
|
@ -185,6 +182,10 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: handle collisions of other objects with with children of linkset.
|
||||
// This is a problem for LinksetCompound since the children are packed into the root.
|
||||
|
||||
return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,7 +316,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
break;
|
||||
case "bulletxna":
|
||||
ret = new BSAPIXNA(engineName, this);
|
||||
// Disable some features that are not implemented in BulletXNA
|
||||
m_log.InfoFormat("{0} Disabling some physics features not implemented by BulletXNA", LogHeader);
|
||||
BSParam.ShouldUseBulletHACD = false;
|
||||
BSParam.ShouldUseSingleConvexHullForPrims = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,7 @@ using System.Text;
|
|||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
|
@ -38,74 +39,39 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
public abstract class BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE]";
|
||||
|
||||
public int referenceCount { get; set; }
|
||||
public DateTime lastReferenced { get; set; }
|
||||
public BulletShape physShapeInfo { get; set; }
|
||||
|
||||
public BSShape()
|
||||
{
|
||||
referenceCount = 0;
|
||||
referenceCount = 1;
|
||||
lastReferenced = DateTime.Now;
|
||||
physShapeInfo = new BulletShape();
|
||||
}
|
||||
public BSShape(BulletShape pShape)
|
||||
{
|
||||
referenceCount = 0;
|
||||
referenceCount = 1;
|
||||
lastReferenced = DateTime.Now;
|
||||
physShapeInfo = pShape;
|
||||
}
|
||||
|
||||
// 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 == BSPhysicsShapeType.SHAPE_CAPSULE)
|
||||
{
|
||||
// an avatar capsule is close to a native shape (it is not shared)
|
||||
ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE,
|
||||
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 have already been created.
|
||||
if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.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);
|
||||
}
|
||||
|
||||
// Avatars have their own unique shape
|
||||
if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR)
|
||||
{
|
||||
// Getting a reference to a compound shape gets you the compound shape with the root prim shape added
|
||||
ret = BSShapeAvatar.GetReference(prim);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret);
|
||||
}
|
||||
|
||||
if (ret == null)
|
||||
ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
|
||||
|
||||
return ret;
|
||||
}
|
||||
private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
BSShapeMesh.GetReference(physicsScene, forceRebuild, prim);
|
||||
BSShapeHull.GetReference(physicsScene, forceRebuild, prim);
|
||||
return null;
|
||||
}
|
||||
// Get another reference to this shape.
|
||||
public abstract BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim);
|
||||
|
||||
// Called when this shape is being used again.
|
||||
public virtual void IncrementReference()
|
||||
// Used internally. External callers should call instance.GetReference() to properly copy/reference
|
||||
// the shape.
|
||||
protected virtual void IncrementReference()
|
||||
{
|
||||
referenceCount++;
|
||||
lastReferenced = DateTime.Now;
|
||||
}
|
||||
|
||||
// Called when this shape is being used again.
|
||||
public virtual void DecrementReference()
|
||||
protected virtual void DecrementReference()
|
||||
{
|
||||
referenceCount--;
|
||||
lastReferenced = DateTime.Now;
|
||||
|
@ -114,22 +80,178 @@ public abstract class BSShape
|
|||
// Release the use of a physical shape.
|
||||
public abstract void Dereference(BSScene physicsScene);
|
||||
|
||||
// Return 'true' if there is an allocated physics physical shape under this class instance.
|
||||
public virtual bool HasPhysicalShape
|
||||
{
|
||||
get
|
||||
{
|
||||
if (physShapeInfo != null)
|
||||
return physShapeInfo.HasPhysicalShape;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public virtual BSPhysicsShapeType ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
if (physShapeInfo != null && physShapeInfo.HasPhysicalShape)
|
||||
ret = physShapeInfo.shapeType;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a string for debugging that uniquily identifies the memory used by this instance
|
||||
public virtual string AddrString
|
||||
{
|
||||
get { return "unknown"; }
|
||||
get
|
||||
{
|
||||
if (physShapeInfo != null)
|
||||
return physShapeInfo.AddrString;
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.Append("<p=");
|
||||
buff.Append(AddrString);
|
||||
if (physShapeInfo == null)
|
||||
{
|
||||
buff.Append(",noPhys");
|
||||
}
|
||||
else
|
||||
{
|
||||
buff.Append(",phy=");
|
||||
buff.Append(physShapeInfo.ToString());
|
||||
}
|
||||
buff.Append(",c=");
|
||||
buff.Append(referenceCount.ToString());
|
||||
buff.Append(">");
|
||||
return buff.ToString();
|
||||
}
|
||||
|
||||
#region Common shape routines
|
||||
// Create a hash of all the shape parameters to be used as a key for this particular shape.
|
||||
public static System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
|
||||
{
|
||||
// level of detail based on size and type of the object
|
||||
float lod = BSParam.MeshLOD;
|
||||
if (pbs.SculptEntry)
|
||||
lod = BSParam.SculptLOD;
|
||||
|
||||
// Mega prims usually get more detail because one can interact with shape approximations at this size.
|
||||
float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
|
||||
if (maxAxis > BSParam.MeshMegaPrimThreshold)
|
||||
lod = BSParam.MeshMegaPrimLOD;
|
||||
|
||||
retLod = lod;
|
||||
return pbs.GetMeshKey(size, 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 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.
|
||||
public static BulletShape VerifyMeshCreated(BSScene physicsScene, BulletShape newShape, BSPhysObject prim)
|
||||
{
|
||||
// If the shape was successfully created, nothing more to do
|
||||
if (newShape.HasPhysicalShape)
|
||||
return newShape;
|
||||
|
||||
// VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been
|
||||
// fetched but we end up here again, the meshing of the asset must have failed.
|
||||
// Prevent trying to keep fetching the mesh by declaring failure.
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||
{
|
||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
|
||||
physicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}",
|
||||
LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,setFailed,objNam={1},tex={2}",
|
||||
prim.LocalID, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
|
||||
if (prim.BaseShape.SculptEntry
|
||||
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed
|
||||
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
|
||||
&& prim.BaseShape.SculptTexture != OMV.UUID.Zero
|
||||
)
|
||||
{
|
||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAsset,objNam={1},tex={2}",
|
||||
prim.LocalID, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
// Multiple requestors will know we're waiting for this asset
|
||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
|
||||
|
||||
BSPhysObject xprim = prim;
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
// physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID);
|
||||
RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod;
|
||||
if (assetProvider != null)
|
||||
{
|
||||
BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
|
||||
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
|
||||
{
|
||||
// physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID);
|
||||
bool assetFound = false;
|
||||
string mismatchIDs = String.Empty; // DEBUG DEBUG
|
||||
if (asset != null && yprim.BaseShape.SculptEntry)
|
||||
{
|
||||
if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
|
||||
{
|
||||
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 normal shape setting since the rebuild is at taint time.
|
||||
yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
|
||||
yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
|
||||
assetFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
|
||||
}
|
||||
}
|
||||
if (!assetFound)
|
||||
{
|
||||
yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
|
||||
yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
|
||||
physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
|
||||
LogHeader, physicsScene.Name);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
|
||||
{
|
||||
physicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}",
|
||||
LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,wasFailed,objNam={1},tex={2}",
|
||||
prim.LocalID, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// While we wait for the mesh defining asset to be loaded, stick in a simple box for the object.
|
||||
BSShape fillShape = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
|
||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,boxTempShape", prim.LocalID);
|
||||
|
||||
return fillShape.physShapeInfo;
|
||||
}
|
||||
|
||||
#endregion // Common shape routines
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
|
@ -139,6 +261,7 @@ public class BSShapeNull : BSShape
|
|||
{
|
||||
}
|
||||
public static BSShape GetReference() { return new BSShapeNull(); }
|
||||
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) { return new BSShapeNull(); }
|
||||
public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ }
|
||||
}
|
||||
|
||||
|
@ -150,24 +273,34 @@ public class BSShapeNative : BSShape
|
|||
{
|
||||
}
|
||||
|
||||
public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim,
|
||||
BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
|
||||
public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim,
|
||||
BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
|
||||
{
|
||||
// Native shapes are not shared and are always built anew.
|
||||
return new BSShapeNative(CreatePhysicalNativeShape(physicsScene, prim, shapeType, shapeKey));
|
||||
}
|
||||
|
||||
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
|
||||
{
|
||||
// Native shapes are not shared so we return a new shape.
|
||||
return new BSShapeNative(CreatePhysicalNativeShape(pPhysicsScene, pPrim,
|
||||
physShapeInfo.shapeType, (FixedShapeKey)physShapeInfo.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
|
||||
if (physShapeInfo.HasPhysicalShape)
|
||||
lock (physShapeInfo)
|
||||
{
|
||||
physicsScene.DetailLog("{0},BSShapeNative.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
|
||||
physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo);
|
||||
if (physShapeInfo.HasPhysicalShape)
|
||||
{
|
||||
physicsScene.DetailLog("{0},BSShapeNative.Dereference,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
|
||||
physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo);
|
||||
}
|
||||
physShapeInfo.Clear();
|
||||
// Garbage collection will free up this instance.
|
||||
}
|
||||
physShapeInfo.Clear();
|
||||
// Garbage collection will free up this instance.
|
||||
}
|
||||
|
||||
private static BulletShape CreatePhysicalNativeShape(BSScene physicsScene, BSPhysObject prim,
|
||||
|
@ -197,7 +330,7 @@ public class BSShapeNative : BSShape
|
|||
physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
|
||||
LogHeader, prim.LocalID, shapeType);
|
||||
}
|
||||
newShape.type = shapeType;
|
||||
newShape.shapeType = shapeType;
|
||||
newShape.isNativeShape = true;
|
||||
newShape.shapeKey = (UInt64)shapeKey;
|
||||
return newShape;
|
||||
|
@ -209,7 +342,7 @@ public class BSShapeNative : BSShape
|
|||
public class BSShapeMesh : BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE MESH]";
|
||||
private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>();
|
||||
public static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>();
|
||||
|
||||
public BSShapeMesh(BulletShape pShape) : base(pShape)
|
||||
{
|
||||
|
@ -217,12 +350,9 @@ public class BSShapeMesh : BSShape
|
|||
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
float lod;
|
||||
System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeMesh,create,oldKey={1},newKey={2},size={3},lod={4}",
|
||||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod);
|
||||
|
||||
BSShapeMesh retMesh;
|
||||
BSShapeMesh retMesh = null;
|
||||
lock (Meshes)
|
||||
{
|
||||
if (Meshes.TryGetValue(newMeshKey, out retMesh))
|
||||
|
@ -232,39 +362,80 @@ public class BSShapeMesh : BSShape
|
|||
}
|
||||
else
|
||||
{
|
||||
retMesh = new BSShapeMesh(new BulletShape());
|
||||
// An instance of this mesh has not been created. Build and remember same.
|
||||
BulletShape newShape = CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||
// Take evasive action if the mesh was not constructed.
|
||||
newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
BulletShape newShape = retMesh.CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||
|
||||
retMesh = new BSShapeMesh(newShape);
|
||||
// Check to see if mesh was created (might require an asset).
|
||||
newShape = VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
if (!newShape.isNativeShape)
|
||||
{
|
||||
// If a mesh was what was created, remember the built shape for later sharing.
|
||||
Meshes.Add(newMeshKey, retMesh);
|
||||
}
|
||||
|
||||
Meshes.Add(newMeshKey, retMesh);
|
||||
retMesh.physShapeInfo = newShape;
|
||||
}
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSShapeMesh,getReference,mesh={1},size={2},lod={3}", prim.LocalID, retMesh, prim.Size, lod);
|
||||
return retMesh;
|
||||
}
|
||||
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
|
||||
{
|
||||
// Another reference to this shape is just counted.
|
||||
IncrementReference();
|
||||
return this;
|
||||
}
|
||||
public override void Dereference(BSScene physicsScene)
|
||||
{
|
||||
lock (Meshes)
|
||||
{
|
||||
this.DecrementReference();
|
||||
physicsScene.DetailLog("{0},BSShapeMesh.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||
// TODO: schedule aging and destruction of unused meshes.
|
||||
}
|
||||
}
|
||||
// Loop through all the known meshes and return the description based on the physical address.
|
||||
public static bool TryGetMeshByPtr(BulletShape pShape, out BSShapeMesh outMesh)
|
||||
{
|
||||
bool ret = false;
|
||||
BSShapeMesh foundDesc = null;
|
||||
lock (Meshes)
|
||||
{
|
||||
foreach (BSShapeMesh sm in Meshes.Values)
|
||||
{
|
||||
if (sm.physShapeInfo.ReferenceSame(pShape))
|
||||
{
|
||||
foundDesc = sm;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
private static BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||
}
|
||||
}
|
||||
outMesh = foundDesc;
|
||||
return ret;
|
||||
}
|
||||
private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
{
|
||||
BulletShape newShape = null;
|
||||
BulletShape newShape = new BulletShape();
|
||||
|
||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
|
||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
|
||||
false, // say it is not physical so a bounding box is not built
|
||||
false // do not cache the mesh and do not use previously built versions
|
||||
false, // do not cache the mesh and do not use previously built versions
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
if (meshData != null)
|
||||
{
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||
{
|
||||
// Release the fetched asset data once it has been used.
|
||||
pbs.SculptData = new byte[0];
|
||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
|
||||
}
|
||||
|
||||
int[] indices = meshData.getIndexListAsInt();
|
||||
int realIndicesIndex = indices.Length;
|
||||
|
@ -302,8 +473,8 @@ public class BSShapeMesh : BSShape
|
|||
}
|
||||
}
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}",
|
||||
BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3);
|
||||
physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,key={1},origTri={2},realTri={3},numVerts={4}",
|
||||
BSScene.DetailLogZero, newMeshKey.ToString("X"), indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3);
|
||||
|
||||
if (realIndicesIndex != 0)
|
||||
{
|
||||
|
@ -326,17 +497,239 @@ public class BSShapeMesh : BSShape
|
|||
public class BSShapeHull : BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE HULL]";
|
||||
private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>();
|
||||
public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>();
|
||||
|
||||
public BSShapeHull(BulletShape pShape) : base(pShape)
|
||||
{
|
||||
}
|
||||
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
return new BSShapeNull();
|
||||
float lod;
|
||||
System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
BSShapeHull retHull = null;
|
||||
lock (Hulls)
|
||||
{
|
||||
if (Hulls.TryGetValue(newHullKey, out retHull))
|
||||
{
|
||||
// The mesh has already been created. Return a new reference to same.
|
||||
retHull.IncrementReference();
|
||||
}
|
||||
else
|
||||
{
|
||||
retHull = new BSShapeHull(new BulletShape());
|
||||
// An instance of this mesh has not been created. Build and remember same.
|
||||
BulletShape newShape = retHull.CreatePhysicalHull(physicsScene, prim, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||
|
||||
// Check to see if hull was created (might require an asset).
|
||||
newShape = VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
if (!newShape.isNativeShape)
|
||||
{
|
||||
// If a mesh was what was created, remember the built shape for later sharing.
|
||||
Hulls.Add(newHullKey, retHull);
|
||||
}
|
||||
retHull.physShapeInfo = newShape;
|
||||
}
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSShapeHull,getReference,hull={1},size={2},lod={3}", prim.LocalID, retHull, prim.Size, lod);
|
||||
return retHull;
|
||||
}
|
||||
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
|
||||
{
|
||||
// Another reference to this shape is just counted.
|
||||
IncrementReference();
|
||||
return this;
|
||||
}
|
||||
public override void Dereference(BSScene physicsScene)
|
||||
{
|
||||
lock (Hulls)
|
||||
{
|
||||
this.DecrementReference();
|
||||
physicsScene.DetailLog("{0},BSShapeHull.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||
// TODO: schedule aging and destruction of unused meshes.
|
||||
}
|
||||
}
|
||||
List<ConvexResult> m_hulls;
|
||||
private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey,
|
||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
{
|
||||
BulletShape newShape = new BulletShape();
|
||||
IntPtr hullPtr = IntPtr.Zero;
|
||||
|
||||
if (BSParam.ShouldUseBulletHACD)
|
||||
{
|
||||
// Build the hull shape from an existing mesh shape.
|
||||
// The mesh should have already been created in Bullet.
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
||||
BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
|
||||
|
||||
if (meshShape.physShapeInfo.HasPhysicalShape)
|
||||
{
|
||||
HACDParams parms;
|
||||
parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull;
|
||||
parms.minClusters = BSParam.BHullMinClusters;
|
||||
parms.compacityWeight = BSParam.BHullCompacityWeight;
|
||||
parms.volumeWeight = BSParam.BHullVolumeWeight;
|
||||
parms.concavity = BSParam.BHullConcavity;
|
||||
parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints);
|
||||
parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
|
||||
parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
|
||||
parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
||||
newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
|
||||
// Now done with the mesh shape.
|
||||
meshShape.Dereference(physicsScene);
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
}
|
||||
if (!newShape.HasPhysicalShape)
|
||||
{
|
||||
// Build a new hull in the physical world using the C# HACD algorigthm.
|
||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
|
||||
if (meshData != null)
|
||||
{
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||
{
|
||||
// Release the fetched asset data once it has been used.
|
||||
pbs.SculptData = new byte[0];
|
||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
|
||||
}
|
||||
|
||||
int[] indices = meshData.getIndexListAsInt();
|
||||
List<OMV.Vector3> vertices = meshData.getVertexList();
|
||||
|
||||
//format conversion from IMesh format to DecompDesc format
|
||||
List<int> convIndices = new List<int>();
|
||||
List<float3> convVertices = new List<float3>();
|
||||
for (int ii = 0; ii < indices.GetLength(0); ii++)
|
||||
{
|
||||
convIndices.Add(indices[ii]);
|
||||
}
|
||||
foreach (OMV.Vector3 vv in vertices)
|
||||
{
|
||||
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 (BSShapeCollection.PrimHasNoCuts(pbs))
|
||||
{
|
||||
maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
|
||||
}
|
||||
}
|
||||
|
||||
// setup and do convex hull conversion
|
||||
m_hulls = new List<ConvexResult>();
|
||||
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);
|
||||
|
||||
physicsScene.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:
|
||||
// convHulls[0] = number of hulls
|
||||
// convHulls[1] = number of vertices in first hull
|
||||
// convHulls[2] = hull centroid X coordinate
|
||||
// convHulls[3] = hull centroid Y coordinate
|
||||
// convHulls[4] = hull centroid Z coordinate
|
||||
// convHulls[5] = first hull vertex X
|
||||
// convHulls[6] = first hull vertex Y
|
||||
// convHulls[7] = first hull vertex Z
|
||||
// convHulls[8] = second hull vertex X
|
||||
// ...
|
||||
// convHulls[n] = number of vertices in second hull
|
||||
// convHulls[n+1] = second hull centroid X coordinate
|
||||
// ...
|
||||
//
|
||||
// TODO: is is very inefficient. Someday change the convex hull generator to return
|
||||
// data structures that do not need to be converted in order to pass to Bullet.
|
||||
// And maybe put the values directly into pinned memory rather than marshaling.
|
||||
int hullCount = m_hulls.Count;
|
||||
int totalVertices = 1; // include one for the count of the hulls
|
||||
foreach (ConvexResult cr in m_hulls)
|
||||
{
|
||||
totalVertices += 4; // add four for the vertex count and centroid
|
||||
totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
|
||||
}
|
||||
float[] convHulls = new float[totalVertices];
|
||||
|
||||
convHulls[0] = (float)hullCount;
|
||||
int jj = 1;
|
||||
foreach (ConvexResult cr in m_hulls)
|
||||
{
|
||||
// copy vertices for index access
|
||||
float3[] verts = new float3[cr.HullVertices.Count];
|
||||
int kk = 0;
|
||||
foreach (float3 ff in cr.HullVertices)
|
||||
{
|
||||
verts[kk++] = ff;
|
||||
}
|
||||
|
||||
// add to the array one hull's worth of data
|
||||
convHulls[jj++] = cr.HullIndices.Count;
|
||||
convHulls[jj++] = 0f; // centroid x,y,z
|
||||
convHulls[jj++] = 0f;
|
||||
convHulls[jj++] = 0f;
|
||||
foreach (int ind in cr.HullIndices)
|
||||
{
|
||||
convHulls[jj++] = verts[ind].x;
|
||||
convHulls[jj++] = verts[ind].y;
|
||||
convHulls[jj++] = verts[ind].z;
|
||||
}
|
||||
}
|
||||
// create the hull data structure in Bullet
|
||||
newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
|
||||
}
|
||||
newShape.shapeKey = newHullKey;
|
||||
}
|
||||
return newShape;
|
||||
}
|
||||
// Callback from convex hull creater with a newly created hull.
|
||||
// Just add it to our collection of hulls for this shape.
|
||||
private void HullReturn(ConvexResult result)
|
||||
{
|
||||
m_hulls.Add(result);
|
||||
return;
|
||||
}
|
||||
// Loop through all the known hulls and return the description based on the physical address.
|
||||
public static bool TryGetHullByPtr(BulletShape pShape, out BSShapeHull outHull)
|
||||
{
|
||||
bool ret = false;
|
||||
BSShapeHull foundDesc = null;
|
||||
lock (Hulls)
|
||||
{
|
||||
foreach (BSShapeHull sh in Hulls.Values)
|
||||
{
|
||||
if (sh.physShapeInfo.ReferenceSame(pShape))
|
||||
{
|
||||
foundDesc = sh;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
outHull = foundDesc;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,14 +737,169 @@ public class BSShapeHull : BSShape
|
|||
public class BSShapeCompound : BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
|
||||
public BSShapeCompound() : base()
|
||||
public BSShapeCompound(BulletShape pShape) : base(pShape)
|
||||
{
|
||||
}
|
||||
public static BSShape GetReference(BSPhysObject prim)
|
||||
{
|
||||
return new BSShapeNull();
|
||||
public static BSShape GetReference(BSScene physicsScene)
|
||||
{
|
||||
// Base compound shapes are not shared so this returns a raw shape.
|
||||
// A built compound shape can be reused in linksets.
|
||||
return new BSShapeCompound(CreatePhysicalCompoundShape(physicsScene));
|
||||
}
|
||||
public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
|
||||
{
|
||||
// Calling this reference means we want another handle to an existing compound shape
|
||||
// (usually linksets) so return this copy.
|
||||
IncrementReference();
|
||||
return this;
|
||||
}
|
||||
// Dereferencing a compound shape releases the hold on all the child shapes.
|
||||
public override void Dereference(BSScene physicsScene)
|
||||
{
|
||||
lock (physShapeInfo)
|
||||
{
|
||||
this.DecrementReference();
|
||||
physicsScene.DetailLog("{0},BSShapeCompound.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||
if (referenceCount <= 0)
|
||||
{
|
||||
if (!physicsScene.PE.IsCompound(physShapeInfo))
|
||||
{
|
||||
// Failed the sanity check!!
|
||||
physicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
|
||||
LogHeader, physShapeInfo.shapeType, physShapeInfo.AddrString);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
|
||||
BSScene.DetailLogZero, physShapeInfo.shapeType, physShapeInfo.AddrString);
|
||||
return;
|
||||
}
|
||||
|
||||
int numChildren = physicsScene.PE.GetNumberOfCompoundChildren(physShapeInfo);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}",
|
||||
BSScene.DetailLogZero, physShapeInfo, numChildren);
|
||||
|
||||
// Loop through all the children dereferencing each.
|
||||
for (int ii = numChildren - 1; ii >= 0; ii--)
|
||||
{
|
||||
BulletShape childShape = physicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(physShapeInfo, ii);
|
||||
DereferenceAnonCollisionShape(physicsScene, childShape);
|
||||
}
|
||||
physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static BulletShape CreatePhysicalCompoundShape(BSScene physicsScene)
|
||||
{
|
||||
BulletShape cShape = physicsScene.PE.CreateCompoundShape(physicsScene.World, false);
|
||||
return cShape;
|
||||
}
|
||||
// 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(BSScene physicsScene, BulletShape pShape)
|
||||
{
|
||||
BSShapeMesh meshDesc;
|
||||
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
|
||||
{
|
||||
meshDesc.Dereference(physicsScene);
|
||||
}
|
||||
else
|
||||
{
|
||||
BSShapeHull hullDesc;
|
||||
if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc))
|
||||
{
|
||||
hullDesc.Dereference(physicsScene);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (physicsScene.PE.IsCompound(pShape))
|
||||
{
|
||||
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
|
||||
recursiveCompound.Dereference(physicsScene);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (physicsScene.PE.IsNativeShape(pShape))
|
||||
{
|
||||
BSShapeNative nativeShape = new BSShapeNative(pShape);
|
||||
nativeShape.Dereference(physicsScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
public class BSShapeConvexHull : BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE CONVEX HULL]";
|
||||
public static Dictionary<System.UInt64, BSShapeConvexHull> ConvexHulls = new Dictionary<System.UInt64, BSShapeConvexHull>();
|
||||
|
||||
public BSShapeConvexHull(BulletShape pShape) : base(pShape)
|
||||
{
|
||||
}
|
||||
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
float lod;
|
||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}",
|
||||
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
||||
|
||||
BSShapeConvexHull retConvexHull = null;
|
||||
lock (ConvexHulls)
|
||||
{
|
||||
if (ConvexHulls.TryGetValue(newMeshKey, out retConvexHull))
|
||||
{
|
||||
// The mesh has already been created. Return a new reference to same.
|
||||
retConvexHull.IncrementReference();
|
||||
}
|
||||
else
|
||||
{
|
||||
retConvexHull = new BSShapeConvexHull(new BulletShape());
|
||||
BulletShape convexShape = null;
|
||||
|
||||
// Get a handle to a mesh to build the hull from
|
||||
BSShape baseMesh = BSShapeMesh.GetReference(physicsScene, false /* forceRebuild */, prim);
|
||||
if (baseMesh.physShapeInfo.isNativeShape)
|
||||
{
|
||||
// We get here if the mesh was not creatable. Could be waiting for an asset from the disk.
|
||||
// In the short term, we return the native shape and a later ForceBodyShapeRebuild should
|
||||
// get back to this code with a buildable mesh.
|
||||
// TODO: not sure the temp native shape is freed when the mesh is rebuilt. When does this get freed?
|
||||
convexShape = baseMesh.physShapeInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexShape = physicsScene.PE.BuildConvexHullShapeFromMesh(physicsScene.World, baseMesh.physShapeInfo);
|
||||
convexShape.shapeKey = newMeshKey;
|
||||
ConvexHulls.Add(convexShape.shapeKey, retConvexHull);
|
||||
}
|
||||
|
||||
// Done with the base mesh
|
||||
baseMesh.Dereference(physicsScene);
|
||||
|
||||
retConvexHull.physShapeInfo = convexShape;
|
||||
}
|
||||
}
|
||||
return retConvexHull;
|
||||
}
|
||||
public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
|
||||
{
|
||||
// Calling this reference means we want another handle to an existing shape
|
||||
// (usually linksets) so return this copy.
|
||||
IncrementReference();
|
||||
return this;
|
||||
}
|
||||
// Dereferencing a compound shape releases the hold on all the child shapes.
|
||||
public override void Dereference(BSScene physicsScene)
|
||||
{
|
||||
lock (ConvexHulls)
|
||||
{
|
||||
this.DecrementReference();
|
||||
physicsScene.DetailLog("{0},BSShapeConvexHull.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||
// TODO: schedule aging and destruction of unused meshes.
|
||||
}
|
||||
}
|
||||
public override void Dereference(BSScene physicsScene) { }
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
|
@ -361,8 +909,12 @@ public class BSShapeAvatar : BSShape
|
|||
public BSShapeAvatar() : base()
|
||||
{
|
||||
}
|
||||
public static BSShape GetReference(BSPhysObject prim)
|
||||
{
|
||||
public static BSShape GetReference(BSPhysObject prim)
|
||||
{
|
||||
return new BSShapeNull();
|
||||
}
|
||||
public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
|
||||
{
|
||||
return new BSShapeNull();
|
||||
}
|
||||
public override void Dereference(BSScene physicsScene) { }
|
||||
|
|
|
@ -68,7 +68,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
|
||||
// This minCoords and maxCoords passed in give the size of the terrain (min and max Z
|
||||
// are the high and low points of the heightmap).
|
||||
public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
|
||||
public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
|
||||
Vector3 minCoords, Vector3 maxCoords)
|
||||
: base(physicsScene, regionBase, id)
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
private void BuildHeightmapTerrain()
|
||||
{
|
||||
// Create the terrain shape from the mapInfo
|
||||
m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape( m_mapInfo.ID,
|
||||
m_mapInfo.terrainShape = m_physicsScene.PE.CreateTerrainShape( m_mapInfo.ID,
|
||||
new Vector3(m_mapInfo.sizeX, m_mapInfo.sizeY, 0), m_mapInfo.minZ, m_mapInfo.maxZ,
|
||||
m_mapInfo.heightMap, 1f, BSParam.TerrainCollisionMargin);
|
||||
|
||||
|
@ -103,26 +103,26 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
|
||||
centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f);
|
||||
|
||||
m_mapInfo.terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape,
|
||||
m_mapInfo.terrainBody = m_physicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape,
|
||||
m_mapInfo.ID, centerPos, Quaternion.Identity);
|
||||
|
||||
// Set current terrain attributes
|
||||
PhysicsScene.PE.SetFriction(m_mapInfo.terrainBody, BSParam.TerrainFriction);
|
||||
PhysicsScene.PE.SetHitFraction(m_mapInfo.terrainBody, BSParam.TerrainHitFraction);
|
||||
PhysicsScene.PE.SetRestitution(m_mapInfo.terrainBody, BSParam.TerrainRestitution);
|
||||
PhysicsScene.PE.SetCollisionFlags(m_mapInfo.terrainBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
m_physicsScene.PE.SetFriction(m_mapInfo.terrainBody, BSParam.TerrainFriction);
|
||||
m_physicsScene.PE.SetHitFraction(m_mapInfo.terrainBody, BSParam.TerrainHitFraction);
|
||||
m_physicsScene.PE.SetRestitution(m_mapInfo.terrainBody, BSParam.TerrainRestitution);
|
||||
m_physicsScene.PE.SetCollisionFlags(m_mapInfo.terrainBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
|
||||
// Return the new terrain to the world of physical objects
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_mapInfo.terrainBody);
|
||||
m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, m_mapInfo.terrainBody);
|
||||
|
||||
// redo its bounding box now that it is in the world
|
||||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_mapInfo.terrainBody);
|
||||
m_physicsScene.PE.UpdateSingleAabb(m_physicsScene.World, m_mapInfo.terrainBody);
|
||||
|
||||
m_mapInfo.terrainBody.collisionType = CollisionType.Terrain;
|
||||
m_mapInfo.terrainBody.ApplyCollisionMask(PhysicsScene);
|
||||
m_mapInfo.terrainBody.ApplyCollisionMask(m_physicsScene);
|
||||
|
||||
// Make it so the terrain will not move or be considered for movement.
|
||||
PhysicsScene.PE.ForceActivationState(m_mapInfo.terrainBody, ActivationState.DISABLE_SIMULATION);
|
||||
m_physicsScene.PE.ForceActivationState(m_mapInfo.terrainBody, ActivationState.DISABLE_SIMULATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -134,9 +134,9 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
{
|
||||
if (m_mapInfo.terrainBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_mapInfo.terrainBody);
|
||||
m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, m_mapInfo.terrainBody);
|
||||
// Frees both the body and the shape.
|
||||
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody);
|
||||
m_physicsScene.PE.DestroyObject(m_physicsScene.World, m_mapInfo.terrainBody);
|
||||
}
|
||||
}
|
||||
m_mapInfo = null;
|
||||
|
@ -155,7 +155,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
catch
|
||||
{
|
||||
// Sometimes they give us wonky values of X and Y. Give a warning and return something.
|
||||
PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
|
||||
m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
|
||||
LogHeader, m_mapInfo.terrainRegionBase, pos);
|
||||
ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
// The passed position is relative to the base of the region.
|
||||
public override float GetWaterLevelAtXYZ(Vector3 pos)
|
||||
{
|
||||
return PhysicsScene.SimpleWaterLevel;
|
||||
return m_physicsScene.SimpleWaterLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,14 +50,14 @@ public abstract class BSTerrainPhys : IDisposable
|
|||
Mesh = 1
|
||||
}
|
||||
|
||||
public BSScene PhysicsScene { get; private set; }
|
||||
protected BSScene m_physicsScene { get; private set; }
|
||||
// Base of the region in world coordinates. Coordinates inside the region are relative to this.
|
||||
public Vector3 TerrainBase { get; private set; }
|
||||
public uint ID { get; private set; }
|
||||
|
||||
public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id)
|
||||
{
|
||||
PhysicsScene = physicsScene;
|
||||
m_physicsScene = physicsScene;
|
||||
TerrainBase = regionBase;
|
||||
ID = id;
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
|
||||
|
||||
// The scene that I am part of
|
||||
private BSScene PhysicsScene { get; set; }
|
||||
private BSScene m_physicsScene { get; set; }
|
||||
|
||||
// The ground plane created to keep thing from falling to infinity.
|
||||
private BulletBody m_groundPlane;
|
||||
|
@ -113,7 +113,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
|
||||
public BSTerrainManager(BSScene physicsScene)
|
||||
{
|
||||
PhysicsScene = physicsScene;
|
||||
m_physicsScene = physicsScene;
|
||||
m_terrains = new Dictionary<Vector3,BSTerrainPhys>();
|
||||
|
||||
// Assume one region of default size
|
||||
|
@ -132,21 +132,21 @@ public sealed class BSTerrainManager : IDisposable
|
|||
// safe to call Bullet in real time. We hope no one is moving prims around yet.
|
||||
public void CreateInitialGroundPlaneAndTerrain()
|
||||
{
|
||||
DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName);
|
||||
DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, m_physicsScene.RegionName);
|
||||
// The ground plane is here to catch things that are trying to drop to negative infinity
|
||||
BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin);
|
||||
m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
|
||||
BulletShape groundPlaneShape = m_physicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin);
|
||||
m_groundPlane = m_physicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
|
||||
BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity);
|
||||
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_groundPlane);
|
||||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_groundPlane);
|
||||
m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, m_groundPlane);
|
||||
m_physicsScene.PE.UpdateSingleAabb(m_physicsScene.World, m_groundPlane);
|
||||
// Ground plane does not move
|
||||
PhysicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION);
|
||||
m_physicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION);
|
||||
// Everything collides with the ground plane.
|
||||
m_groundPlane.collisionType = CollisionType.Groundplane;
|
||||
m_groundPlane.ApplyCollisionMask(PhysicsScene);
|
||||
m_groundPlane.ApplyCollisionMask(m_physicsScene);
|
||||
|
||||
BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
|
||||
BSTerrainPhys initialTerrain = new BSTerrainHeightmap(m_physicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
|
||||
lock (m_terrains)
|
||||
{
|
||||
// Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain.
|
||||
|
@ -157,12 +157,12 @@ public sealed class BSTerrainManager : IDisposable
|
|||
// Release all the terrain structures we might have allocated
|
||||
public void ReleaseGroundPlaneAndTerrain()
|
||||
{
|
||||
DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName);
|
||||
DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, m_physicsScene.RegionName);
|
||||
if (m_groundPlane.HasPhysicalBody)
|
||||
{
|
||||
if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane))
|
||||
if (m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, m_groundPlane))
|
||||
{
|
||||
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_groundPlane);
|
||||
m_physicsScene.PE.DestroyObject(m_physicsScene.World, m_groundPlane);
|
||||
}
|
||||
m_groundPlane.Clear();
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
float[] localHeightMap = heightMap;
|
||||
// If there are multiple requests for changes to the same terrain between ticks,
|
||||
// only do that last one.
|
||||
PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
|
||||
m_physicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
|
||||
{
|
||||
if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
|
||||
{
|
||||
|
@ -219,7 +219,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
private void AddMegaRegionChildTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
|
||||
{
|
||||
// Since we are called by another region's thread, the action must be rescheduled onto our processing thread.
|
||||
PhysicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + minCoords.ToString(), id, delegate()
|
||||
m_physicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + minCoords.ToString(), id, delegate()
|
||||
{
|
||||
UpdateTerrain(id, heightMap, minCoords, maxCoords);
|
||||
});
|
||||
|
@ -318,26 +318,26 @@ public sealed class BSTerrainManager : IDisposable
|
|||
// TODO: redo terrain implementation selection to allow other base types than heightMap.
|
||||
private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
|
||||
{
|
||||
PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
|
||||
LogHeader, PhysicsScene.RegionName, terrainRegionBase,
|
||||
m_physicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
|
||||
LogHeader, m_physicsScene.RegionName, terrainRegionBase,
|
||||
(BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation);
|
||||
BSTerrainPhys newTerrainPhys = null;
|
||||
switch ((int)BSParam.TerrainImplementation)
|
||||
{
|
||||
case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
|
||||
newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
|
||||
newTerrainPhys = new BSTerrainHeightmap(m_physicsScene, terrainRegionBase, id,
|
||||
heightMap, minCoords, maxCoords);
|
||||
break;
|
||||
case (int)BSTerrainPhys.TerrainImplementation.Mesh:
|
||||
newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id,
|
||||
newTerrainPhys = new BSTerrainMesh(m_physicsScene, terrainRegionBase, id,
|
||||
heightMap, minCoords, maxCoords);
|
||||
break;
|
||||
default:
|
||||
PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
|
||||
LogHeader,
|
||||
(int)BSParam.TerrainImplementation,
|
||||
m_physicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
|
||||
LogHeader,
|
||||
(int)BSParam.TerrainImplementation,
|
||||
BSParam.TerrainImplementation,
|
||||
PhysicsScene.RegionName, terrainRegionBase);
|
||||
m_physicsScene.RegionName, terrainRegionBase);
|
||||
break;
|
||||
}
|
||||
return newTerrainPhys;
|
||||
|
@ -429,8 +429,8 @@ public sealed class BSTerrainManager : IDisposable
|
|||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, PhysicsScene.RegionName, tX, tY);
|
||||
m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, m_physicsScene.RegionName, tX, tY);
|
||||
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}",
|
||||
BSScene.DetailLogZero, pos, terrainBaseXYZ);
|
||||
}
|
||||
|
@ -451,8 +451,8 @@ public sealed class BSTerrainManager : IDisposable
|
|||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}",
|
||||
LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret);
|
||||
m_physicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}",
|
||||
LogHeader, m_physicsScene.RegionName, pos, terrainBaseXYZ, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
|
||||
private void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
PhysicsScene.PhysicsLogging.Write(msg, args);
|
||||
m_physicsScene.PhysicsLogging.Write(msg, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
BulletShape m_terrainShape;
|
||||
BulletBody m_terrainBody;
|
||||
|
||||
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
|
||||
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
|
||||
: base(physicsScene, regionBase, id)
|
||||
{
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
}
|
||||
|
||||
// Create terrain mesh from a heightmap.
|
||||
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
|
||||
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
|
||||
Vector3 minCoords, Vector3 maxCoords)
|
||||
: base(physicsScene, regionBase, id)
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
if (BSParam.TerrainMeshMagnification == 1)
|
||||
{
|
||||
// If a magnification of one, use the old routine that is tried and true.
|
||||
meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene,
|
||||
meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh(m_physicsScene,
|
||||
initialMap, m_sizeX, m_sizeY, // input size
|
||||
Vector3.Zero, // base for mesh
|
||||
out indicesCount, out indices, out verticesCount, out vertices);
|
||||
|
@ -88,7 +88,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
else
|
||||
{
|
||||
// Other magnifications use the newer routine
|
||||
meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh2(PhysicsScene,
|
||||
meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh2(m_physicsScene,
|
||||
initialMap, m_sizeX, m_sizeY, // input size
|
||||
BSParam.TerrainMeshMagnification,
|
||||
physicsScene.TerrainManager.DefaultRegionSize,
|
||||
|
@ -98,21 +98,21 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
if (!meshCreationSuccess)
|
||||
{
|
||||
// DISASTER!!
|
||||
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID);
|
||||
PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
|
||||
m_physicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID);
|
||||
m_physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
|
||||
// Something is very messed up and a crash is in our future.
|
||||
return;
|
||||
}
|
||||
|
||||
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,id={1},indices={2},indSz={3},vertices={4},vertSz={5}",
|
||||
m_physicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,id={1},indices={2},indSz={3},vertices={4},vertSz={5}",
|
||||
BSScene.DetailLogZero, ID, indicesCount, indices.Length, verticesCount, vertices.Length);
|
||||
|
||||
m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices);
|
||||
m_terrainShape = m_physicsScene.PE.CreateMeshShape(m_physicsScene.World, indicesCount, indices, verticesCount, vertices);
|
||||
if (!m_terrainShape.HasPhysicalShape)
|
||||
{
|
||||
// DISASTER!!
|
||||
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID);
|
||||
PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
|
||||
m_physicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID);
|
||||
m_physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
|
||||
// Something is very messed up and a crash is in our future.
|
||||
return;
|
||||
}
|
||||
|
@ -120,52 +120,52 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
Vector3 pos = regionBase;
|
||||
Quaternion rot = Quaternion.Identity;
|
||||
|
||||
m_terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot);
|
||||
m_terrainBody = m_physicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot);
|
||||
if (!m_terrainBody.HasPhysicalBody)
|
||||
{
|
||||
// DISASTER!!
|
||||
PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
|
||||
m_physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
|
||||
// Something is very messed up and a crash is in our future.
|
||||
return;
|
||||
}
|
||||
physicsScene.PE.SetShapeCollisionMargin(m_terrainShape, BSParam.TerrainCollisionMargin);
|
||||
|
||||
// Set current terrain attributes
|
||||
PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
|
||||
PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
|
||||
PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold);
|
||||
PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
m_physicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
|
||||
m_physicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
|
||||
m_physicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
|
||||
m_physicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold);
|
||||
m_physicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
|
||||
// Static objects are not very massive.
|
||||
PhysicsScene.PE.SetMassProps(m_terrainBody, 0f, Vector3.Zero);
|
||||
m_physicsScene.PE.SetMassProps(m_terrainBody, 0f, Vector3.Zero);
|
||||
|
||||
// Put the new terrain to the world of physical objects
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_terrainBody);
|
||||
m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, m_terrainBody);
|
||||
|
||||
// Redo its bounding box now that it is in the world
|
||||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_terrainBody);
|
||||
m_physicsScene.PE.UpdateSingleAabb(m_physicsScene.World, m_terrainBody);
|
||||
|
||||
m_terrainBody.collisionType = CollisionType.Terrain;
|
||||
m_terrainBody.ApplyCollisionMask(PhysicsScene);
|
||||
m_terrainBody.ApplyCollisionMask(m_physicsScene);
|
||||
|
||||
if (BSParam.UseSingleSidedMeshes)
|
||||
{
|
||||
PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id);
|
||||
PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
|
||||
m_physicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id);
|
||||
m_physicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
|
||||
}
|
||||
|
||||
// Make it so the terrain will not move or be considered for movement.
|
||||
PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION);
|
||||
m_physicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (m_terrainBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody);
|
||||
m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, m_terrainBody);
|
||||
// Frees both the body and the shape.
|
||||
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody);
|
||||
m_physicsScene.PE.DestroyObject(m_physicsScene.World, m_terrainBody);
|
||||
m_terrainBody.Clear();
|
||||
m_terrainShape.Clear();
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
catch
|
||||
{
|
||||
// Sometimes they give us wonky values of X and Y. Give a warning and return something.
|
||||
PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
|
||||
m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
|
||||
LogHeader, TerrainBase, pos);
|
||||
ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
// The passed position is relative to the base of the region.
|
||||
public override float GetWaterLevelAtXYZ(Vector3 pos)
|
||||
{
|
||||
return PhysicsScene.SimpleWaterLevel;
|
||||
return m_physicsScene.SimpleWaterLevel;
|
||||
}
|
||||
|
||||
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
|
||||
|
|
|
@ -104,11 +104,11 @@ public class BulletShape
|
|||
{
|
||||
public BulletShape()
|
||||
{
|
||||
type = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
shapeType = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE;
|
||||
isNativeShape = false;
|
||||
}
|
||||
public BSPhysicsShapeType type;
|
||||
public BSPhysicsShapeType shapeType;
|
||||
public System.UInt64 shapeKey;
|
||||
public bool isNativeShape;
|
||||
|
||||
|
@ -133,7 +133,7 @@ public class BulletShape
|
|||
buff.Append("<p=");
|
||||
buff.Append(AddrString);
|
||||
buff.Append(",s=");
|
||||
buff.Append(type.ToString());
|
||||
buff.Append(shapeType.ToString());
|
||||
buff.Append(",k=");
|
||||
buff.Append(shapeKey.ToString("X"));
|
||||
buff.Append(",n=");
|
||||
|
@ -224,42 +224,42 @@ public static class BulletSimData
|
|||
// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code
|
||||
// but, instead, use references to this dictionary. Finding and debugging
|
||||
// collision flag problems will be made easier.
|
||||
public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeMasks
|
||||
public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeMasks
|
||||
= new Dictionary<CollisionType, CollisionTypeFilterGroup>()
|
||||
{
|
||||
{ CollisionType.Avatar,
|
||||
new CollisionTypeFilterGroup(CollisionType.Avatar,
|
||||
(uint)CollisionFilterGroups.BCharacterGroup,
|
||||
{ CollisionType.Avatar,
|
||||
new CollisionTypeFilterGroup(CollisionType.Avatar,
|
||||
(uint)CollisionFilterGroups.BCharacterGroup,
|
||||
(uint)CollisionFilterGroups.BAllGroup)
|
||||
},
|
||||
{ CollisionType.Groundplane,
|
||||
new CollisionTypeFilterGroup(CollisionType.Groundplane,
|
||||
(uint)CollisionFilterGroups.BGroundPlaneGroup,
|
||||
{ CollisionType.Groundplane,
|
||||
new CollisionTypeFilterGroup(CollisionType.Groundplane,
|
||||
(uint)CollisionFilterGroups.BGroundPlaneGroup,
|
||||
(uint)CollisionFilterGroups.BAllGroup)
|
||||
},
|
||||
{ CollisionType.Terrain,
|
||||
new CollisionTypeFilterGroup(CollisionType.Terrain,
|
||||
(uint)CollisionFilterGroups.BTerrainGroup,
|
||||
{ CollisionType.Terrain,
|
||||
new CollisionTypeFilterGroup(CollisionType.Terrain,
|
||||
(uint)CollisionFilterGroups.BTerrainGroup,
|
||||
(uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup))
|
||||
},
|
||||
{ CollisionType.Static,
|
||||
new CollisionTypeFilterGroup(CollisionType.Static,
|
||||
(uint)CollisionFilterGroups.BStaticGroup,
|
||||
{ CollisionType.Static,
|
||||
new CollisionTypeFilterGroup(CollisionType.Static,
|
||||
(uint)CollisionFilterGroups.BStaticGroup,
|
||||
(uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup))
|
||||
},
|
||||
{ CollisionType.Dynamic,
|
||||
new CollisionTypeFilterGroup(CollisionType.Dynamic,
|
||||
(uint)CollisionFilterGroups.BSolidGroup,
|
||||
{ CollisionType.Dynamic,
|
||||
new CollisionTypeFilterGroup(CollisionType.Dynamic,
|
||||
(uint)CollisionFilterGroups.BSolidGroup,
|
||||
(uint)(CollisionFilterGroups.BAllGroup))
|
||||
},
|
||||
{ CollisionType.VolumeDetect,
|
||||
new CollisionTypeFilterGroup(CollisionType.VolumeDetect,
|
||||
(uint)CollisionFilterGroups.BSensorTrigger,
|
||||
{ CollisionType.VolumeDetect,
|
||||
new CollisionTypeFilterGroup(CollisionType.VolumeDetect,
|
||||
(uint)CollisionFilterGroups.BSensorTrigger,
|
||||
(uint)(~CollisionFilterGroups.BSensorTrigger))
|
||||
},
|
||||
{ CollisionType.LinksetChild,
|
||||
new CollisionTypeFilterGroup(CollisionType.LinksetChild,
|
||||
(uint)CollisionFilterGroups.BLinksetChildGroup,
|
||||
new CollisionTypeFilterGroup(CollisionType.LinksetChild,
|
||||
(uint)CollisionFilterGroups.BLinksetChildGroup,
|
||||
(uint)(CollisionFilterGroups.BNoneGroup))
|
||||
// (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup))
|
||||
},
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
PROBLEMS TO LOOK INTO
|
||||
=================================================
|
||||
Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly.
|
||||
Have to rez new vehicle and delete the old to fix situation.
|
||||
Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd
|
||||
position state where it will not settle onto ground properly, etc
|
||||
Two of Nebadon vehicles in a sim max the CPU. This is new.
|
||||
A sitting, active vehicle bobs up and down a small amount.
|
||||
|
||||
CURRENT PRIORITIES
|
||||
=================================================
|
||||
Use the HACD convex hull routine in Bullet rather than the C# version.
|
||||
|
@ -11,6 +20,8 @@ Deleting a linkset while standing on the root will leave the physical shape of t
|
|||
Linkset child rotations.
|
||||
Nebadon spiral tube has middle sections which are rotated wrong.
|
||||
Select linked spiral tube. Delink and note where the middle section ends up.
|
||||
Refarb compound linkset creation to create a pseudo-root for center-of-mass
|
||||
Let children change their shape to physical indendently and just add shapes to compound
|
||||
Vehicle angular vertical attraction
|
||||
vehicle angular banking
|
||||
Center-of-gravity
|
||||
|
@ -27,14 +38,13 @@ llLookAt
|
|||
Avatars walking up stairs (HALF DONE)
|
||||
Avatar movement
|
||||
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
|
||||
walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
|
||||
walking up stairs is not calibrated correctly (stairs out of Kepler cabin) (DONE)
|
||||
avatar capsule rotation completed (NOT DONE - Bullet's capsule shape is not the solution)
|
||||
Vehicle script tuning/debugging
|
||||
Avanti speed script
|
||||
Weapon shooter script
|
||||
Move material definitions (friction, ...) into simulator.
|
||||
Add material densities to the material types.
|
||||
Terrain detail: double terrain mesh detail
|
||||
One sided meshes? Should terrain be built into a closed shape?
|
||||
When meshes get partially wedged into the terrain, they cannot push themselves out.
|
||||
It is possible that Bullet processes collisions whether entering or leaving a mesh.
|
||||
|
@ -42,6 +52,9 @@ One sided meshes? Should terrain be built into a closed shape?
|
|||
|
||||
VEHICLES TODO LIST:
|
||||
=================================================
|
||||
LINEAR_MOTOR_DIRECTION values should be clamped to reasonable numbers.
|
||||
What are the limits in SL?
|
||||
Same for other velocity settings.
|
||||
UBit improvements to remove rubber-banding of avatars sitting on vehicle child prims:
|
||||
https://github.com/UbitUmarov/Ubit-opensim
|
||||
Border crossing with linked vehicle causes crash
|
||||
|
@ -347,4 +360,5 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
|||
DONE 20130120: BulletSim properly applies force in vehicle relative coordinates.
|
||||
Nebadon vehicles turning funny in arena (DONE)
|
||||
Lock axis (DONE 20130401)
|
||||
Terrain detail: double terrain mesh detail (DONE)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
; Modular configurations
|
||||
; Set path to directory for modular ini files...
|
||||
; The Robust.exe process must have R/W access to the location
|
||||
ConfigDirectory = "/home/opensim/etc/Configs"
|
||||
ConfigDirectory = "."
|
||||
|
||||
[ServiceList]
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
; Modular configurations
|
||||
; Set path to directory for modular ini files...
|
||||
; The Robust.exe process must have R/W access to the location
|
||||
ConfigDirectory = "/home/opensim/etc/Configs"
|
||||
ConfigDirectory = "."
|
||||
|
||||
[ServiceList]
|
||||
AssetServiceConnector = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector"
|
||||
|
|
Loading…
Reference in New Issue