BulletSim: first round of conversion from direct BulletSimAPI interfacing by BulletSim core to using the BulletSimAPITemplate. Physical object creation and destruction first.

0.7.5-pf-bulletsim
Robert Adams 2012-12-29 21:43:43 -08:00
parent 203588e3c0
commit 48f718f39f
12 changed files with 235 additions and 839 deletions

View File

@ -210,8 +210,7 @@ public sealed class BSCharacter : BSPhysObject
if (!Flying && !IsColliding)
{
stepVelocity.Z = _velocity.Z;
DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}",
LocalID, stepVelocity);
// DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
}
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
@ -231,8 +230,7 @@ public sealed class BSCharacter : BSPhysObject
AddForce(moveForce, false, true);
}
*/
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
LocalID, stepVelocity, _velocity, Mass, moveForce);
// DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
AddForce(moveForce, false, true);
});
}
@ -736,7 +734,7 @@ public sealed class BSCharacter : BSPhysObject
PhysicsScene.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);
// DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce);

View File

@ -359,7 +359,7 @@ public sealed class BSLinksetCompound : BSLinkset
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
BulletShape newShape = cPrim.PhysShape;
cPrim.PhysShape = saveShape;
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot);
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot);
}
else
{
@ -371,7 +371,7 @@ public sealed class BSLinksetCompound : BSLinkset
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
}
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot);
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
}
}
return false; // 'false' says to move onto the next child in the list
@ -386,7 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset
Rebuilding = false;
}
BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);
PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
// DEBUG: see of inter-linkset collisions are causing problems for constraint linksets.
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,

View File

@ -845,7 +845,7 @@ public sealed 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)BulletSimAPI.GetBodyType2(PhysBody.ptr);
CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(PhysBody);
if (makeSolid)
{
// Verify the previous code created the correct shape for this type of thing.

View File

@ -50,6 +50,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public string BulletSimVersion = "?";
// The handle to the underlying managed or unmanaged version of Bullet being used.
public BulletSimAPITemplate PE;
public Dictionary<uint, BSPhysObject> PhysObjects;
public BSShapeCollection Shapes;
@ -187,12 +190,15 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Allocate pinned memory to pass parameters.
UnmanagedParams = new ConfigurationParameters[1];
m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned);
// Set default values for physics parameters plus any overrides from the ini file
GetInitialParameterValues(config);
// allocate more pinned memory close to the above in an attempt to get the memory all together
// For the moment, only one version of the interface
PE = new BSAPIUnman();
// Allocate more pinned memory. Do this early to try and get all pinned memory close together.
m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned);
m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];

View File

@ -174,7 +174,7 @@ public sealed class BSShapeCollection : IDisposable
// Zero any reference to the shape so it is not freed when the body is deleted.
BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, body);
});
}
}
@ -261,7 +261,7 @@ public sealed class BSShapeCollection : IDisposable
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime);
if (shapeCallback != null) shapeCallback(shape);
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
}
else
{
@ -342,26 +342,26 @@ public sealed class BSShapeCollection : IDisposable
return;
}
int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr);
int numChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(shape);
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
for (int ii = numChildren - 1; ii >= 0; ii--)
{
IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii);
BulletShape childShape = PhysicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(shape, ii);
DereferenceAnonCollisionShape(childShape);
}
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
}
// Sometimes we have a pointer to a collision shape but don't know what type it is.
// Figure out type and call the correct dereference routine.
// Called at taint-time.
private void DereferenceAnonCollisionShape(IntPtr cShape)
private void DereferenceAnonCollisionShape(BulletShape shapeInfo)
{
MeshDesc meshDesc;
HullDesc hullDesc;
BulletShape shapeInfo = new BulletShape(cShape);
IntPtr cShape = shapeInfo.ptr;
if (TryGetMeshByPtr(cShape, out meshDesc))
{
shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH;
@ -382,7 +382,7 @@ public sealed class BSShapeCollection : IDisposable
}
else
{
if (BulletSimAPI.IsNativeShape2(cShape))
if (PhysicsScene.PE.IsNativeShape(shapeInfo))
{
shapeInfo.isNativeShape = true;
shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
@ -570,19 +570,15 @@ public sealed class BSShapeCollection : IDisposable
if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
{
// The proper scale has been calculated in the prim.
newShape = new BulletShape(
// Bullet's capsule total height is the passed "height + (radius * 2)" so, the base
// capsule is radius of 0.5f (1 diameter) and height of two (1.0f + 0.5f * 2)".
// This must be taken into account when computing the scaling of the capsule.
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
, shapeType);
newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale);
if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
}
else
{
// Native shapes are scaled in Bullet so set the scaling to the size
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
newShape = PhysicsScene.PE.BuildNativeShape(PhysicsScene.World, nativeShapeData);
}
if (!newShape.HasPhysicalShape)
{
@ -629,13 +625,14 @@ public sealed class BSShapeCollection : IDisposable
private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{
BulletShape newShape = new BulletShape();
IMesh meshData = null;
IntPtr meshPtr = IntPtr.Zero;
MeshDesc meshDesc;
if (Meshes.TryGetValue(newMeshKey, out meshDesc))
{
// If the mesh has already been built just use it.
meshPtr = meshDesc.ptr;
newShape = new BulletShape(meshDesc.ptr, BSPhysicsShapeType.SHAPE_MESH);
}
else
{
@ -658,11 +655,10 @@ public sealed class BSShapeCollection : IDisposable
// m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
// LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count);
meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World,
indices.GetLength(0), indices, vertices.Count, verticesAsFloats);
}
}
BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH);
newShape.shapeKey = newMeshKey;
return newShape;
@ -700,12 +696,14 @@ public sealed class BSShapeCollection : IDisposable
private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{
BulletShape newShape = new BulletShape();
IntPtr hullPtr = IntPtr.Zero;
HullDesc hullDesc;
if (Hulls.TryGetValue(newHullKey, out hullDesc))
{
// If the hull shape already is created, just use it.
hullPtr = hullDesc.ptr;
newShape = new BulletShape(hullDesc.ptr, BSPhysicsShapeType.SHAPE_HULL);
}
else
{
@ -793,11 +791,10 @@ public sealed class BSShapeCollection : IDisposable
}
}
// create the hull data structure in Bullet
hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls);
newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
}
}
BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL);
newShape.shapeKey = newHullKey;
return newShape;
@ -819,12 +816,12 @@ public sealed class BSShapeCollection : IDisposable
// Don't need to do this as the shape is freed when the new root shape is created below.
// DereferenceShape(prim.PhysShape, true, shapeCallback);
BulletShape cShape = new BulletShape(
BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND);
BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false);
// Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
CreateGeomMeshOrHull(prim, shapeCallback);
BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
PhysicsScene.PE.AddChildShapeToCompoundShape(cShape, prim.PhysShape, OMV.Vector3.Zero, OMV.Quaternion.Identity);
if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
prim.LocalID, cShape, prim.PhysShape);
@ -932,7 +929,7 @@ public sealed class BSShapeCollection : IDisposable
// If not a solid object, body is a GhostObject. Otherwise a RigidBody.
if (!mustRebuild)
{
CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr);
CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(prim.PhysBody);
if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY
|| !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT)
{
@ -947,20 +944,16 @@ public sealed class BSShapeCollection : IDisposable
DereferenceBody(prim.PhysBody, true, bodyCallback);
BulletBody aBody;
IntPtr bodyPtr = IntPtr.Zero;
if (prim.IsSolid)
{
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
aBody = PhysicsScene.PE.CreateBodyFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody);
}
else
{
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
aBody = PhysicsScene.PE.CreateGhostFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody);
}
aBody = new BulletBody(prim.LocalID, bodyPtr);
ReferenceBody(aBody, true);

View File

@ -126,7 +126,8 @@ public class BSShapeNative : BSShape
BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
{
// Native shapes are not shared and are always built anew.
return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
//return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
return null;
}
private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
@ -141,6 +142,7 @@ public class BSShapeNative : BSShape
nativeShapeData.HullKey = (ulong)shapeKey;
/*
if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
{
ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale);
@ -157,15 +159,18 @@ public class BSShapeNative : BSShape
}
type = shapeType;
key = (UInt64)shapeKey;
*/
}
// Make this reference to the physical shape go away since native shapes are not shared.
public override void Dereference(BSScene physicsScene)
{
/*
// Native shapes are not tracked and are released immediately
physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr);
ptr = IntPtr.Zero;
// Garbage collection will free up this instance.
*/
}
}

View File

@ -105,9 +105,8 @@ 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 = new BulletBody(m_mapInfo.ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr,
m_mapInfo.ID, centerPos, Quaternion.Identity));
m_mapInfo.terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape,
m_mapInfo.ID, centerPos, Quaternion.Identity);
// Set current terrain attributes
BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction);
@ -139,7 +138,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
// Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody);
BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr);
}
}

View File

@ -137,9 +137,9 @@ public sealed class BSTerrainManager : IDisposable
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
BSParam.TerrainCollisionMargin),
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
Vector3.Zero, Quaternion.Identity));
m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity);
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr);
// Ground plane does not move
@ -160,7 +160,7 @@ public sealed class BSTerrainManager : IDisposable
{
if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr))
{
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_groundPlane);
}
m_groundPlane.Clear();
}

View File

@ -91,9 +91,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}",
ID, indicesCount, indices.Length, verticesCount, vertices.Length);
m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
indicesCount, indices, verticesCount, vertices),
BSPhysicsShapeType.SHAPE_MESH);
m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices);
if (!m_terrainShape.HasPhysicalShape)
{
// DISASTER!!
@ -106,7 +104,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
Vector3 pos = regionBase;
Quaternion rot = Quaternion.Identity;
m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot));
m_terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot);
if (!m_terrainBody.HasPhysicalBody)
{
// DISASTER!!
@ -143,7 +141,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
// Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ CRASHES
VEHICLES TODO LIST:
=================================================
Angular motor direction is global coordinates rather than local coordinates
Border crossing with linked vehicle causes crash
Vehicles (Move smoothly)
Add vehicle collisions so IsColliding is properly reported.
@ -78,7 +79,7 @@ Small physical objects do not interact correctly
Create chain of .5x.5x.1 torui and make all but top physical so to hang.
The chain will fall apart and pairs will dance around on ground
Chains of 1x1x.2 will stay connected but will dance.
Chains above 2x2x.4 are move stable and get stablier as torui get larger.
Chains above 2x2x.4 are more stable and get stablier as torui get larger.
Add PID motor for avatar movement (slow to stop, ...)
setForce should set a constant force. Different than AddImpulse.
Implement raycast.
@ -100,9 +101,13 @@ More efficient memory usage when passing hull information from BSPrim to BulletS
Avatar movement motor check for zero or small movement. Somehow suppress small movements
when avatar has stopped and is just standing. Simple test for near zero has
the problem of preventing starting up (increase from zero) especially when falling.
Physical and phantom will drop through the terrain
LINKSETS
======================================================
Offset the center of the linkset to be the geometric center of all the prims
Not quite the same as the center-of-gravity
Linksets should allow collisions to individual children
Add LocalID to children shapes in LinksetCompound and create events for individuals
LinksetCompound: when one of the children changes orientation (like tires

View File

@ -1747,6 +1747,7 @@
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
<Reference name="BulletXNA.dll" path="../../../../bin/"/>
<Reference name="log4net.dll" path="../../../../bin/"/>
<Files>