BulletSim: add class and infrastructure for shape and object

tracking in the C# code. Needed for the changing body type
    (to and from GhostObjects) for volumeDetect.
connector_plugin
Robert Adams 2012-09-19 08:21:29 -07:00
parent 91efccabdc
commit a27e4ce6cb
5 changed files with 193 additions and 40 deletions

View File

@ -474,12 +474,13 @@ public sealed class BSPrim : BSPhysObject
*/
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
// Make solid or not (do things bounce off or pass through this object)
// This is done first because it can change the collisionObject type.
MakeSolid(IsSolid);
// Set up the object physicalness (does gravity and collisions move this object)
MakeDynamic(IsStatic);
// Make solid or not (do things bounce off or pass through this object)
MakeSolid(IsSolid);
// Arrange for collisions events if the simulator wants them
EnableCollisions(SubscribedEvents());
@ -554,17 +555,51 @@ public sealed class BSPrim : BSPhysObject
}
// "Making solid" means that other object will not pass through this object.
// To make transparent, we create a Bullet ghost object.
// Note: This expects to be called from the UpdatePhysicalParameters() routine as
// 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(BSBody.Ptr);
/*
if (makeSolid)
{
// Easy in Bullet -- just remove the object flag that controls collision response
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0)
{
// Solid things are made out of rigid bodies. Remove this old body from the world
// and use this shape in a new rigid body.
BulletBody oldBody = BSBody;
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
BSBody = new BulletBody(LocalID, BulletSimAPI.CreateBodyFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation));
BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, oldBody.Ptr);
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
}
}
else
{
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0)
{
// Non-solid things are made out of ghost objects. Remove this old body from the world
// and use this shape in a new rigid body.
BulletBody oldBody = BSBody;
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
BSBody = new BulletBody(LocalID,
BulletSimAPI.CreateGhostFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation));
if (BSBody.Ptr == IntPtr.Zero)
{
m_log.ErrorFormat("{0} BSPrim.MakeSolid: failed creation of ghost object. LocalID=[1}", LogHeader, LocalID);
BSBody = oldBody;
}
else
{
BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, oldBody.Ptr);
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
}
}
}
*/
}
// Turn on or off the flag controlling whether collision events are returned to the simulator.

View File

@ -73,8 +73,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public string BulletSimVersion = "?";
public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
public Dictionary<uint, BSPhysObject> PhysObjects;
public BSShapeCollection Shapes;
// Keeping track of the objects with collisions so we can report begin and end of a collision
public HashSet<BSPhysObject> ObjectsWithCollisions = new HashSet<BSPhysObject>();
public HashSet<BSPhysObject> ObjectsWithNoMoreCollisions = new HashSet<BSPhysObject>();
// Keep track of all the avatars so we can send them a collision event
@ -203,6 +205,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public override void Initialise(IMesher meshmerizer, IConfigSource config)
{
mesher = meshmerizer;
_taintedObjects = new List<TaintCallbackEntry>();
PhysObjects = new Dictionary<uint, BSPhysObject>();
Shapes = new BSShapeCollection(this);
// Allocate pinned memory to pass parameters.
m_params = new ConfigurationParameters[1];
m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned);
@ -216,12 +223,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
mesher = meshmerizer;
_taintedObjects = new List<TaintCallbackEntry>();
// Enable very detailed logging.
// By creating an empty logger when not logging, the log message invocation code
// can be left in and every call doesn't have to check for null.
// can be left in and every call doesn't have to check for null.
if (m_physicsLoggingEnabled)
{
PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes);
@ -252,7 +256,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// a child in a mega-region.
// Turns out that Bullet really doesn't care about the extents of the simulated
// area. It tracks active objects no matter where they are.
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyrightD
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using OMV = OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public class BSShapeCollection : IDisposable
{
protected BSScene PhysicsScene { get; set; }
public BSShapeCollection(BSScene physScene)
{
PhysicsScene = physScene;
}
public void Dispose()
{
}
// Track another user of a body
public void ReferenceBody(BulletBody shape)
{
}
// Release the usage of a body
public void DereferenceBody(BulletBody shape)
{
}
// Track another user of the shape
public void ReferenceShape(BulletShape shape)
{
}
// Release the usage of a shape
public void DereferenceShape(BulletShape shape)
{
}
}
}

View File

@ -107,7 +107,9 @@ public class BSTerrainManager
public void CreateInitialGroundPlaneAndTerrain()
{
// The ground plane is here to catch things that are trying to drop to negative infinity
BulletShape groundPlaneShape = new BulletShape(BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN));
BulletShape groundPlaneShape = new BulletShape(
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN),
ShapeData.PhysicsShapeType.SHAPE_GROUNDPLANE);
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.Ptr, Vector3.Zero, Quaternion.Identity));
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, m_groundPlane.Ptr);
@ -297,7 +299,8 @@ public class BSTerrainManager
centerPos.Z = minZ + ((maxZ - minZ) / 2f);
// Create the terrain shape from the mapInfo
mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr),
ShapeData.PhysicsShapeType.SHAPE_TERRAIN);
mapInfo.terrainBody = new BulletBody(mapInfo.ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.Ptr,

View File

@ -38,31 +38,54 @@ namespace OpenSim.Region.Physics.BulletSPlugin {
// The physics engine controller class created at initialization
public struct BulletSim
{
public BulletSim(uint worldId, BSScene bss, IntPtr xx) { worldID = worldId; scene = bss; Ptr = xx; }
public BulletSim(uint worldId, BSScene bss, IntPtr xx)
{
worldID = worldId; scene = bss; Ptr = xx;
}
public uint worldID;
// The scene is only in here so very low level routines have a handle to print debug/error messages
public BSScene scene;
public IntPtr Ptr;
}
public struct BulletShape
{
public BulletShape(IntPtr xx) { Ptr = xx; }
public IntPtr Ptr;
}
// An allocated Bullet btRigidBody
public struct BulletBody
{
public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; }
public BulletBody(uint id, IntPtr xx)
{
ID = id;
Ptr = xx;
}
public IntPtr Ptr;
public uint ID;
}
public struct BulletShape
{
public BulletShape(IntPtr xx)
{
Ptr = xx;
type=ShapeData.PhysicsShapeType.SHAPE_UNKNOWN;
hashKey = 0;
}
public BulletShape(IntPtr xx, ShapeData.PhysicsShapeType typ)
{
Ptr = xx;
type = typ;
hashKey = 0;
}
public IntPtr Ptr;
public ShapeData.PhysicsShapeType type;
public ulong hashKey;
}
// An allocated Bullet btConstraint
public struct BulletConstraint
{
public BulletConstraint(IntPtr xx) { Ptr = xx; }
public BulletConstraint(IntPtr xx)
{
Ptr = xx;
}
public IntPtr Ptr;
}
@ -96,14 +119,14 @@ public class BulletHeightMapInfo
// ===============================================================================
[StructLayout(LayoutKind.Sequential)]
public struct ConvexHull
public struct ConvexHull
{
Vector3 Offset;
int VertexCount;
Vector3[] Vertices;
}
[StructLayout(LayoutKind.Sequential)]
public struct ShapeData
public struct ShapeData
{
public enum PhysicsShapeType
{
@ -114,7 +137,9 @@ public struct ShapeData
SHAPE_CYLINDER = 4,
SHAPE_SPHERE = 5,
SHAPE_MESH = 6,
SHAPE_HULL = 7
SHAPE_HULL = 7,
SHAPE_GROUNDPLANE = 8,
SHAPE_TERRAIN = 9,
};
public uint ID;
public PhysicsShapeType Type;
@ -136,7 +161,7 @@ public struct ShapeData
public const float numericFalse = 0f;
}
[StructLayout(LayoutKind.Sequential)]
public struct SweepHit
public struct SweepHit
{
public uint ID;
public float Fraction;
@ -227,7 +252,17 @@ public enum ActivationState : uint
ISLAND_SLEEPING,
WANTS_DEACTIVATION,
DISABLE_DEACTIVATION,
DISABLE_SIMULATION
DISABLE_SIMULATION,
}
public enum CollisionObjectTypes : int
{
CO_COLLISION_OBJECT = 1 << 0,
CO_RIGID_BODY = 1 << 1,
CO_GHOST_OBJECT = 1 << 2,
CO_SOFT_BODY = 1 << 3,
CO_HF_FLUID = 1 << 4,
CO_USER_TYPE = 1 << 5,
}
// Values used by Bullet and BulletSim to control object properties.
@ -313,8 +348,8 @@ public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg
public static extern string GetVersion();
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
int maxCollisions, IntPtr collisionArray,
public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
int maxCollisions, IntPtr collisionArray,
int maxUpdates, IntPtr updateArray,
DebugLogCallback logRoutine);
@ -333,19 +368,19 @@ public static extern bool UpdateParameter(uint worldID, uint localID,
// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep,
out int updatedEntityCount,
public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep,
out int updatedEntityCount,
out IntPtr updatedEntitiesPtr,
out int collidersCount,
out IntPtr collidersPtr);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool CreateHull(uint worldID, System.UInt64 meshKey,
public static extern bool CreateHull(uint worldID, System.UInt64 meshKey,
int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls
);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool CreateMesh(uint worldID, System.UInt64 meshKey,
public static extern bool CreateMesh(uint worldID, System.UInt64 meshKey,
int indexCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices
);
@ -459,7 +494,7 @@ public static extern void Shutdown2(IntPtr sim);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep,
out int updatedEntityCount,
out int updatedEntityCount,
out IntPtr updatedEntitiesPtr,
out int collidersCount,
out IntPtr collidersPtr);
@ -470,8 +505,8 @@ public static extern bool PushUpdate2(IntPtr obj);
// =====================================================================================
// Mesh, hull, shape and body creation helper routines
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateMeshShape2(IntPtr world,
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
public static extern IntPtr CreateMeshShape2(IntPtr world,
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@ -503,12 +538,18 @@ public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern int GetBodyType2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateGhostFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr AllocateBodyInfo2(IntPtr obj);
@ -521,11 +562,11 @@ public static extern void DestroyObject2(IntPtr sim, IntPtr obj);
// =====================================================================================
// Terrain creation and helper routines
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords,
public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords,
[MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords,
public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords,
[MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@ -563,7 +604,7 @@ public static extern void SetConstraintEnable2(IntPtr constrain, float numericTr
public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetFrames2(IntPtr constrain,
public static extern bool SetFrames2(IntPtr constrain,
Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]