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,9 +223,6 @@ 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.
@ -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;
}
@ -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;
@ -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.
@ -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);