diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c8aad8d41d..0defb24f76 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -167,9 +167,8 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Do this after the object has been added to the world - BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, - (uint)CollisionFilterGroups.AvatarGroup, - (uint)CollisionFilterGroups.AvatarMask); + PhysBody.collisionType = CollisionType.Avatar; + PhysBody.ApplyCollisionMask(); } public override void RequestPhysicsterseUpdate() diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 19c29cc3f6..c9c9c2cc10 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -661,14 +661,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Collision filter can be set only when the object is in the world - if (PhysBody.collisionGroup != 0 || PhysBody.collisionMask != 0) - { - if (!BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, (uint)PhysBody.collisionGroup, (uint)PhysBody.collisionMask)) - { - PhysicsScene.Logger.ErrorFormat("{0} Failure setting prim collision mask. localID={1}, grp={2:X}, mask={3:X}", - LogHeader, LocalID, PhysBody.collisionGroup, PhysBody.collisionMask); - } - } + PhysBody.ApplyCollisionMask(); // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that @@ -713,11 +706,11 @@ public sealed class BSPrim : BSPhysObject // Start it out sleeping and physical actions could wake it up. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); + // This collides like a static object + PhysBody.collisionType = CollisionType.Static; + // There can be special things needed for implementing linksets Linkset.MakeStatic(this); - - PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup; - PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; } else { @@ -755,16 +748,15 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); - // There might be special things needed for implementing linksets. - Linkset.MakeDynamic(this); + // 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. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); - // BulletSimAPI.Activate2(BSBody.ptr, true); - PhysBody.collisionGroup = CollisionFilterGroups.ObjectGroup; - PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; + // There might be special things needed for implementing linksets. + Linkset.MakeDynamic(this); } } @@ -791,8 +783,9 @@ public sealed class BSPrim : BSPhysObject m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); } CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - PhysBody.collisionGroup = CollisionFilterGroups.VolumeDetectGroup; - PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; + + // Change collision info from a static object to a ghosty collision object + PhysBody.collisionType = CollisionType.VolumeDetect; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 2d379bb110..2b120d60db 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -121,9 +121,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.SetCollisionGroupMask2(m_mapInfo.terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainGroup, - (uint)CollisionFilterGroups.TerrainMask); + m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; + m_mapInfo.terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c28d69d934..5dbd8ce6cf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -140,8 +140,8 @@ public sealed class BSTerrainManager // Ground plane does not move BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); // Everything collides with the ground plane. - BulletSimAPI.SetCollisionGroupMask2(m_groundPlane.ptr, - (uint)CollisionFilterGroups.GroundPlaneGroup, (uint)CollisionFilterGroups.GroundPlaneMask); + m_groundPlane.collisionType = CollisionType.Groundplane; + m_groundPlane.ApplyCollisionMask(); // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 34730063b7..6dc0d92857 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -130,9 +130,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); - BulletSimAPI.SetCollisionGroupMask2(m_terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainGroup, - (uint)CollisionFilterGroups.TerrainMask); + m_terrainBody.collisionType = CollisionType.Terrain; + m_terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 1559025ad5..962b5408f0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -32,110 +33,6 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -// Classes to allow some type checking for the API -// These hold pointers to allocated objects in the unmanaged space. - -// The physics engine controller class created at initialization -public struct BulletSim -{ - public BulletSim(uint worldId, BSScene bss, IntPtr xx) - { - ptr = xx; - worldID = worldId; - physicsScene = bss; - } - public IntPtr ptr; - public uint worldID; - // The scene is only in here so very low level routines have a handle to print debug/error messages - public BSScene physicsScene; -} - -// An allocated Bullet btRigidBody -public struct BulletBody -{ - public BulletBody(uint id) : this(id, IntPtr.Zero) - { - } - public BulletBody(uint id, IntPtr xx) - { - ID = id; - ptr = xx; - collisionGroup = 0; - collisionMask = 0; - } - public IntPtr ptr; - public uint ID; - public CollisionFilterGroups collisionGroup; - public CollisionFilterGroups collisionMask; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -public struct BulletShape -{ - public BulletShape(IntPtr xx) - { - ptr = xx; - type=BSPhysicsShapeType.SHAPE_UNKNOWN; - shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; - isNativeShape = false; - } - public BulletShape(IntPtr xx, BSPhysicsShapeType typ) - { - ptr = xx; - type = typ; - shapeKey = 0; - isNativeShape = false; - } - public IntPtr ptr; - public BSPhysicsShapeType type; - public System.UInt64 shapeKey; - public bool isNativeShape; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - // Constraint type values as defined by Bullet public enum ConstraintType : int { @@ -149,50 +46,6 @@ public enum ConstraintType : int MAX_CONSTRAINT_TYPE } -// An allocated Bullet btConstraint -public struct BulletConstraint -{ - public BulletConstraint(IntPtr xx) - { - ptr = xx; - } - public IntPtr ptr; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } -} - -// An allocated HeightMapThing which holds various heightmap info. -// Made a class rather than a struct so there would be only one -// instance of this and C# will pass around pointers rather -// than making copies. -public class BulletHeightMapInfo -{ - public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { - ID = id; - Ptr = xx; - heightMap = hm; - terrainRegionBase = Vector3.Zero; - minCoords = new Vector3(100f, 100f, 25f); - maxCoords = new Vector3(101f, 101f, 26f); - minZ = maxZ = 0f; - sizeX = sizeY = 256f; - } - public uint ID; - public IntPtr Ptr; - public float[] heightMap; - public Vector3 terrainRegionBase; - public Vector3 minCoords; - public Vector3 maxCoords; - public float sizeX, sizeY; - public float minZ, maxZ; - public BulletShape terrainShape; - public BulletBody terrainBody; -} - // =============================================================================== [StructLayout(LayoutKind.Sequential)] public struct ConvexHull @@ -385,21 +238,15 @@ public enum CollisionFlags : uint BS_FLOATS_ON_WATER = 1 << 11, BS_VEHICLE_COLLISIONS = 1 << 12, BS_NONE = 0, - BS_ALL = 0xFFFFFFFF, - - // These are the collision flags switched depending on physical state. - // The other flags are used for other things and should not be fooled with. - BS_ACTIVE = CF_STATIC_OBJECT - | CF_KINEMATIC_OBJECT - | CF_NO_CONTACT_RESPONSE + BS_ALL = 0xFFFFFFFF }; -// Values for collisions groups and masks +// Values f collisions groups and masks public enum CollisionFilterGroups : uint { // Don't use the bit definitions!! Define the use in a // filter/mask definition below. This way collision interactions - // are more easily debugged. + // are more easily found and debugged. BNoneGroup = 0, BDefaultGroup = 1 << 0, BStaticGroup = 1 << 1, @@ -413,24 +260,8 @@ public enum CollisionFilterGroups : uint BTerrainGroup = 1 << 11, BRaycastGroup = 1 << 12, BSolidGroup = 1 << 13, - BLinksetGroup = 1 << 14, - - // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarGroup = BCharacterGroup, - AvatarMask = BAllGroup, - ObjectGroup = BSolidGroup, - ObjectMask = BAllGroup, - StaticObjectGroup = BStaticGroup, - StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much - LinksetGroup = BLinksetGroup, - LinksetMask = BAllGroup & ~BLinksetGroup, // linkset objects don't collide with each other - VolumeDetectGroup = BSensorTrigger, - VolumeDetectMask = ~BSensorTrigger, - TerrainGroup = BTerrainGroup, - TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide - GroundPlaneGroup = BGroundPlaneGroup, - GroundPlaneMask = BAllGroup - + // BLinksetGroup = xx // a linkset proper is either static or dynamic + BLinksetChildGroup = 1 << 14, }; // CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 @@ -457,7 +288,7 @@ public enum ConstraintParamAxis : int // =============================================================================== static class BulletSimAPI { - +// =============================================================================== // Link back to the managed code for outputting log messages [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs new file mode 100755 index 0000000000..e5c4777a17 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -0,0 +1,282 @@ +/* + * 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 +{ +// Classes to allow some type checking for the API +// These hold pointers to allocated objects in the unmanaged space. + +// The physics engine controller class created at initialization +public struct BulletSim +{ + public BulletSim(uint worldId, BSScene bss, IntPtr xx) + { + ptr = xx; + worldID = worldId; + physicsScene = bss; + } + public IntPtr ptr; + public uint worldID; + // The scene is only in here so very low level routines have a handle to print debug/error messages + public BSScene physicsScene; +} + +// An allocated Bullet btRigidBody +public struct BulletBody +{ + public BulletBody(uint id) : this(id, IntPtr.Zero) + { + } + public BulletBody(uint id, IntPtr xx) + { + ID = id; + ptr = xx; + collisionType = CollisionType.Static; + } + public IntPtr ptr; + public uint ID; + public CollisionType collisionType; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } + + // Apply the specificed collision mask into the physical world + public void ApplyCollisionMask() + { + // 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 + // a collision body that is in the world.) + BulletSimAPI.SetCollisionGroupMask2(ptr, + BulletSimData.CollisionTypeMasks[collisionType].group, + BulletSimData.CollisionTypeMasks[collisionType].mask); + } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +public struct BulletShape +{ + public BulletShape(IntPtr xx) + { + ptr = xx; + type=BSPhysicsShapeType.SHAPE_UNKNOWN; + shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; + isNativeShape = false; + } + public BulletShape(IntPtr xx, BSPhysicsShapeType typ) + { + ptr = xx; + type = typ; + shapeKey = 0; + isNativeShape = false; + } + public IntPtr ptr; + public BSPhysicsShapeType type; + public System.UInt64 shapeKey; + public bool isNativeShape; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +// An allocated Bullet btConstraint +public struct BulletConstraint +{ + public BulletConstraint(IntPtr xx) + { + ptr = xx; + } + public IntPtr ptr; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } +} + +// An allocated HeightMapThing which holds various heightmap info. +// Made a class rather than a struct so there would be only one +// instance of this and C# will pass around pointers rather +// than making copies. +public class BulletHeightMapInfo +{ + public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { + ID = id; + Ptr = xx; + heightMap = hm; + terrainRegionBase = OMV.Vector3.Zero; + minCoords = new OMV.Vector3(100f, 100f, 25f); + maxCoords = new OMV.Vector3(101f, 101f, 26f); + minZ = maxZ = 0f; + sizeX = sizeY = 256f; + } + public uint ID; + public IntPtr Ptr; + public float[] heightMap; + public OMV.Vector3 terrainRegionBase; + public OMV.Vector3 minCoords; + public OMV.Vector3 maxCoords; + public float sizeX, sizeY; + public float minZ, maxZ; + public BulletShape terrainShape; + public BulletBody terrainBody; +} + +// The general class of collsion object. +public enum CollisionType +{ + Avatar, + Groundplane, + Terrain, + Static, + Dynamic, + VolumeDetect, + // Linkset, // A linkset proper should be either Static or Dynamic + LinksetChild, + Unknown +}; + +// Hold specification of group and mask collision flags for a CollisionType +public struct CollisionTypeFilterGroup +{ + public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) + { + type = t; + group = g; + mask = m; + } + public CollisionType type; + public uint group; + public uint mask; +}; + + /* + // The collsion filters and masked are defined in one place -- don't want them scattered + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetGroup, + LinksetMask = BAllGroup, + LinksetChildGroup = BLinksetChildGroup, + LinksetChildMask = BNoneGroup, // Linkset children disappear from the world + VolumeDetectGroup = BSensorTrigger, + VolumeDetectMask = ~BSensorTrigger, + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup + */ + +public static class BulletSimData +{ + +// Map of collisionTypes to flags for collision groups and masks. +// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code +// but, instead, user references to this dictionary. This makes finding and debugging +// collision flag usage easier. +public static Dictionary CollisionTypeMasks + = new Dictionary() +{ + { CollisionType.Avatar, + new CollisionTypeFilterGroup(CollisionType.Avatar, + (uint)CollisionFilterGroups.BCharacterGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Groundplane, + new CollisionTypeFilterGroup(CollisionType.Groundplane, + (uint)CollisionFilterGroups.BGroundPlaneGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Terrain, + new CollisionTypeFilterGroup(CollisionType.Terrain, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BAllGroup & ~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, + (uint)(CollisionFilterGroups.BAllGroup)) + }, + { CollisionType.VolumeDetect, + new CollisionTypeFilterGroup(CollisionType.VolumeDetect, + (uint)CollisionFilterGroups.BSensorTrigger, + (uint)(~CollisionFilterGroups.BSensorTrigger)) + }, + { CollisionType.LinksetChild, + new CollisionTypeFilterGroup(CollisionType.LinksetChild, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BNoneGroup)) + }, +}; + +} +}