BulletSim: subclass Bullet[World|Body|Shape|Constraint] for unmanaged

to have pointers and managed to have objects.
Initial paste of XNA code. Commented out.
0.7.5-pf-bulletsim
Robert Adams 2013-01-01 09:30:49 -08:00
parent a0739a80a8
commit 04132d3af4
6 changed files with 1806 additions and 278 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -362,7 +362,7 @@ public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
// ===================================================================================== // =====================================================================================
public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin);
public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
float scaleFactor, float collisionMargin); float scaleFactor, float collisionMargin);
// ===================================================================================== // =====================================================================================

View File

@ -300,7 +300,7 @@ public sealed class BSPrim : BSPhysObject
// All positions are given in world positions. // All positions are given in world positions.
if (_position == value) if (_position == value)
{ {
DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation);
return; return;
} }
_position = value; _position = value;
@ -894,21 +894,26 @@ public sealed class BSPrim : BSPhysObject
// Object MUST NOT already be in the world. // Object MUST NOT already be in the world.
// This routine exists because some assorted properties get mangled by adding to the world. // This routine exists because some assorted properties get mangled by adding to the world.
internal void AddObjectToPhysicalWorld() internal void AddObjectToPhysicalWorld()
{ {
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
// TODO: Fix this. Total kludge because adding object to world resets its gravity to default. // TODO: Fix this. Total kludge because adding object to world resets its gravity to default.
// Replace this when the new AddObjectToWorld function is complete. // Replace this when the new AddObjectToWorld function is complete.
PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity());
// Collision filter can be set only when the object is in the world // Collision filter can be set only when the object is in the world
if (!PhysBody.ApplyCollisionMask(PhysicsScene)) if (!PhysBody.ApplyCollisionMask(PhysicsScene))
{ {
m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType);
} }
}
else
{
m_log.ErrorFormat("{0} Attempt to add physical object without body. id={1}", LogHeader, LocalID);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,addObjectWithoutBody,cType={1}", LocalID, PhysBody.collisionType);
} }
} }

View File

@ -45,7 +45,7 @@ public sealed class BSShapeCollection : IDisposable
// Description of a Mesh // Description of a Mesh
private struct MeshDesc private struct MeshDesc
{ {
public IntPtr ptr; public BulletShape shape;
public int referenceCount; public int referenceCount;
public DateTime lastReferenced; public DateTime lastReferenced;
public UInt64 shapeKey; public UInt64 shapeKey;
@ -55,7 +55,7 @@ public sealed class BSShapeCollection : IDisposable
// Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations.
private struct HullDesc private struct HullDesc
{ {
public IntPtr ptr; public BulletShape shape;
public int referenceCount; public int referenceCount;
public DateTime lastReferenced; public DateTime lastReferenced;
public UInt64 shapeKey; public UInt64 shapeKey;
@ -173,7 +173,7 @@ public sealed class BSShapeCollection : IDisposable
} }
// Zero any reference to the shape so it is not freed when the body is deleted. // Zero any reference to the shape so it is not freed when the body is deleted.
PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, new BulletShape()); PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); PhysicsScene.PE.DestroyObject(PhysicsScene.World, body);
}); });
} }
@ -202,7 +202,7 @@ public sealed class BSShapeCollection : IDisposable
else else
{ {
// This is a new reference to a mesh // This is a new reference to a mesh
meshDesc.ptr = shape.ptr; meshDesc.shape = shape.Clone();
meshDesc.shapeKey = shape.shapeKey; meshDesc.shapeKey = shape.shapeKey;
// We keep a reference to the underlying IMesh data so a hull can be built // We keep a reference to the underlying IMesh data so a hull can be built
meshDesc.referenceCount = 1; meshDesc.referenceCount = 1;
@ -225,7 +225,7 @@ public sealed class BSShapeCollection : IDisposable
else else
{ {
// This is a new reference to a hull // This is a new reference to a hull
hullDesc.ptr = shape.ptr; hullDesc.shape = shape.Clone();
hullDesc.shapeKey = shape.shapeKey; hullDesc.shapeKey = shape.shapeKey;
hullDesc.referenceCount = 1; hullDesc.referenceCount = 1;
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
@ -361,15 +361,14 @@ public sealed class BSShapeCollection : IDisposable
MeshDesc meshDesc; MeshDesc meshDesc;
HullDesc hullDesc; HullDesc hullDesc;
IntPtr cShape = shapeInfo.ptr; if (TryGetMeshByPtr(shapeInfo, out meshDesc))
if (TryGetMeshByPtr(cShape, out meshDesc))
{ {
shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH;
shapeInfo.shapeKey = meshDesc.shapeKey; shapeInfo.shapeKey = meshDesc.shapeKey;
} }
else else
{ {
if (TryGetHullByPtr(cShape, out hullDesc)) if (TryGetHullByPtr(shapeInfo, out hullDesc))
{ {
shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL; shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL;
shapeInfo.shapeKey = hullDesc.shapeKey; shapeInfo.shapeKey = hullDesc.shapeKey;
@ -632,7 +631,7 @@ public sealed class BSShapeCollection : IDisposable
if (Meshes.TryGetValue(newMeshKey, out meshDesc)) if (Meshes.TryGetValue(newMeshKey, out meshDesc))
{ {
// If the mesh has already been built just use it. // If the mesh has already been built just use it.
newShape = new BulletShape(meshDesc.ptr, BSPhysicsShapeType.SHAPE_MESH); newShape = meshDesc.shape.Clone();
} }
else else
{ {
@ -703,7 +702,7 @@ public sealed class BSShapeCollection : IDisposable
if (Hulls.TryGetValue(newHullKey, out hullDesc)) if (Hulls.TryGetValue(newHullKey, out hullDesc))
{ {
// If the hull shape already is created, just use it. // If the hull shape already is created, just use it.
newShape = new BulletShape(hullDesc.ptr, BSPhysicsShapeType.SHAPE_HULL); newShape = hullDesc.shape.Clone();
} }
else else
{ {
@ -965,13 +964,13 @@ public sealed class BSShapeCollection : IDisposable
return ret; return ret;
} }
private bool TryGetMeshByPtr(IntPtr addr, out MeshDesc outDesc) private bool TryGetMeshByPtr(BulletShape shape, out MeshDesc outDesc)
{ {
bool ret = false; bool ret = false;
MeshDesc foundDesc = new MeshDesc(); MeshDesc foundDesc = new MeshDesc();
foreach (MeshDesc md in Meshes.Values) foreach (MeshDesc md in Meshes.Values)
{ {
if (md.ptr == addr) if (md.shape.ReferenceSame(shape))
{ {
foundDesc = md; foundDesc = md;
ret = true; ret = true;
@ -983,13 +982,13 @@ public sealed class BSShapeCollection : IDisposable
return ret; return ret;
} }
private bool TryGetHullByPtr(IntPtr addr, out HullDesc outDesc) private bool TryGetHullByPtr(BulletShape shape, out HullDesc outDesc)
{ {
bool ret = false; bool ret = false;
HullDesc foundDesc = new HullDesc(); HullDesc foundDesc = new HullDesc();
foreach (HullDesc hd in Hulls.Values) foreach (HullDesc hd in Hulls.Values)
{ {
if (hd.ptr == addr) if (hd.shape.ReferenceSame(shape))
{ {
foundDesc = hd; foundDesc = hd;
ret = true; ret = true;

View File

@ -33,17 +33,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
// Classes to allow some type checking for the API // Classes to allow some type checking for the API
// These hold pointers to allocated objects in the unmanaged space. // These hold pointers to allocated objects in the unmanaged space.
// These classes are subclassed by the various physical implementations of
// objects. In particular, there is a version for physical instances in
// unmanaged memory ("unman") and one for in managed memory ("XNA").
// Currently, the instances of these classes are a reference to a
// physical representation and this has no releationship to other
// instances. Someday, refarb the usage of these classes so each instance
// refers to a particular physical instance and this class controls reference
// counts and such. This should be done along with adding BSShapes.
// The physics engine controller class created at initialization
public class BulletWorld public class BulletWorld
{ {
public BulletWorld(uint worldId, BSScene bss, IntPtr xx) public BulletWorld(uint worldId, BSScene bss)
{ {
ptr = xx;
worldID = worldId; worldID = worldId;
physicsScene = bss; physicsScene = bss;
} }
public IntPtr ptr;
public uint worldID; public uint worldID;
// The scene is only in here so very low level routines have a handle to print debug/error messages // The scene is only in here so very low level routines have a handle to print debug/error messages
public BSScene physicsScene; public BSScene physicsScene;
@ -52,27 +58,19 @@ public class BulletWorld
// An allocated Bullet btRigidBody // An allocated Bullet btRigidBody
public class BulletBody public class BulletBody
{ {
public BulletBody(uint id) : this(id, IntPtr.Zero) public BulletBody(uint id)
{
}
public BulletBody(uint id, IntPtr xx)
{ {
ID = id; ID = id;
ptr = xx;
collisionType = CollisionType.Static; collisionType = CollisionType.Static;
} }
public IntPtr ptr;
public uint ID; public uint ID;
public CollisionType collisionType; public CollisionType collisionType;
public void Clear() public virtual void Clear() { }
{ public virtual bool HasPhysicalBody { get { return false; } }
ptr = IntPtr.Zero;
}
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
// Apply the specificed collision mask into the physical world // Apply the specificed collision mask into the physical world
public bool ApplyCollisionMask(BSScene physicsScene) public virtual bool ApplyCollisionMask(BSScene physicsScene)
{ {
// Should assert the body has been added to the physical world. // Should assert the body has been added to the physical world.
// (The collision masks are stored in the collision proxy cache which only exists for // (The collision masks are stored in the collision proxy cache which only exists for
@ -83,12 +81,9 @@ public class BulletBody
} }
// Used for log messages for a unique display of the memory/object allocated to this instance // Used for log messages for a unique display of the memory/object allocated to this instance
public string AddrString public virtual string AddrString
{ {
get get { return "unknown"; }
{
return ptr.ToString("X");
}
} }
public override string ToString() public override string ToString()
@ -108,38 +103,26 @@ public class BulletBody
public class BulletShape public class BulletShape
{ {
public BulletShape() public BulletShape()
: this(IntPtr.Zero, BSPhysicsShapeType.SHAPE_UNKNOWN)
{ {
} type = BSPhysicsShapeType.SHAPE_UNKNOWN;
public BulletShape(IntPtr xx)
: this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN)
{
}
public BulletShape(IntPtr xx, BSPhysicsShapeType typ)
{
ptr = xx;
type = typ;
shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE;
isNativeShape = false; isNativeShape = false;
} }
public IntPtr ptr;
public BSPhysicsShapeType type; public BSPhysicsShapeType type;
public System.UInt64 shapeKey; public System.UInt64 shapeKey;
public bool isNativeShape; public bool isNativeShape;
public void Clear() public virtual void Clear() { }
{ public virtual bool HasPhysicalShape { get { return false; } }
ptr = IntPtr.Zero; // Make another reference to this physical object.
} public virtual BulletShape Clone() { return new BulletShape(); }
public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } // Return 'true' if this and other refer to the same physical object
public virtual bool ReferenceSame(BulletShape xx) { return false; }
// Used for log messages for a unique display of the memory/object allocated to this instance // Used for log messages for a unique display of the memory/object allocated to this instance
public string AddrString public virtual string AddrString
{ {
get get { return "unknown"; }
{
return ptr.ToString("X");
}
} }
public override string ToString() public override string ToString()
@ -161,25 +144,16 @@ public class BulletShape
// An allocated Bullet btConstraint // An allocated Bullet btConstraint
public class BulletConstraint public class BulletConstraint
{ {
public BulletConstraint(IntPtr xx) public BulletConstraint()
{ {
ptr = xx;
} }
public IntPtr ptr; public virtual void Clear() { }
public virtual bool HasPhysicalConstraint { get { return false; } }
public void Clear()
{
ptr = IntPtr.Zero;
}
public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } }
// Used for log messages for a unique display of the memory/object allocated to this instance // Used for log messages for a unique display of the memory/object allocated to this instance
public string AddrString public virtual string AddrString
{ {
get get { return "unknown"; }
{
return ptr.ToString("X");
}
} }
} }