diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs index 683bc51163..ff271fefb0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs @@ -44,7 +44,7 @@ public class BS6DofConstraint : BSConstraint m_body1 = obj1; m_body2 = obj2; m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, + BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, frame1, frame1rot, frame2, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); @@ -59,7 +59,7 @@ public class BS6DofConstraint : BSConstraint m_body1 = obj1; m_body2 = obj2; m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraintToPoint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, + BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, joinPoint, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); m_enabled = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 014cd99a11..e4b1dd4f2d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -114,7 +114,7 @@ public class BSCharacter : BSPhysObject // Set the buoyancy for flying. This will be refactored when all the settings happen in C# BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); - BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID)); + BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID)); }); return; @@ -189,10 +189,10 @@ public class BSCharacter : BSPhysObject _rotationalVelocity = OMV.Vector3.Zero; // Zero some other properties directly into the physics engine - BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); - BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); - BulletSimAPI.ClearForces2(BSBody.Ptr); + BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); + BulletSimAPI.ClearForces2(BSBody.ptr); } public override void LockAngularMotion(OMV.Vector3 axis) { return; } @@ -437,7 +437,7 @@ public class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() { DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); + BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); }); } else diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index 1376a29bbf..c21252ba0c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -49,7 +49,7 @@ public abstract class BSConstraint : IDisposable if (m_enabled) { m_enabled = false; - bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); + bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.Ptr); m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); m_constraint.Ptr = System.IntPtr.Zero; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs index d68048bd0a..a6e4235ae4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs @@ -1,55 +1,55 @@ -/* - * 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 OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - -class BSHingeConstraint : BSConstraint -{ - public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, - Vector3 pivotInA, Vector3 pivotInB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.CreateHingeConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, - pivotInA, pivotInB, - axisInA, axisInB, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - m_enabled = true; - } - -} - -} +/* + * 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 OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +class BSHingeConstraint : BSConstraint +{ + public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 pivotInA, Vector3 pivotInB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + m_constraint = new BulletConstraint( + BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + pivotInA, pivotInB, + axisInA, axisInB, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + m_enabled = true; + } + +} + +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 1e8fe522b1..84a7fac0ab 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -282,10 +282,10 @@ public class BSLinkset { // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); - BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); + BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); foreach (BSPhysObject child in m_children) { - BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); + BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); } /* // The root prim takes on the weight of the whole linkset @@ -442,7 +442,7 @@ public class BSLinkset PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); // Make the child refresh its location - BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr); + BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr); } // Remove linkage between myself and any possible children I might have diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 70a10b15f5..6a9fe50894 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -121,8 +121,8 @@ public abstract class BSPhysObject : PhysicsActor // if someone has subscribed for collision events.... if (SubscribedEvents()) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); - // DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", - // LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); + DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", + LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); ret = true; } return ret; @@ -147,7 +147,7 @@ public abstract class BSPhysObject : PhysicsActor if (CollisionCollection.Count == 0) PhysicsScene.ObjectsWithNoMoreCollisions.Add(this); - // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); + DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); // The collisionCollection structure is passed around in the simulator. @@ -158,7 +158,8 @@ public abstract class BSPhysObject : PhysicsActor // Subscribe for collision events. // Parameter is the millisecond rate the caller wishes collision events to occur. - public override void SubscribeEvents(int ms) { + public override void SubscribeEvents(int ms) { + DetailLog("{0},BSScene.SubscribeEvents,subscribing,ms={1}", BSScene.DetailLogZero, ms); SubscribedEventsMs = ms; if (ms > 0) { @@ -167,7 +168,7 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } else @@ -177,10 +178,11 @@ public abstract class BSPhysObject : PhysicsActor } } public override void UnSubscribeEvents() { + DetailLog("{0},BSScene.UnSubscribeEvents,unsubscribing", BSScene.DetailLogZero); SubscribedEventsMs = 0; PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } // Return 'true' if the simulator wants collision events diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b7643795c0..5be2b1b6fe 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -24,6 +24,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +// Uncomment this it enable code to do all shape an body memory management +// in the C# code. +#define CSHARP_BODY_MANAGEMENT + using System; using System.Reflection; using System.Collections.Generic; @@ -36,6 +41,7 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet; namespace OpenSim.Region.Physics.BulletSPlugin { + [Serializable] public sealed class BSPrim : BSPhysObject { @@ -126,7 +132,7 @@ public sealed class BSPrim : BSPhysObject { CreateGeomAndObject(true); - CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); + CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.ptr); }); } @@ -246,10 +252,10 @@ public sealed class BSPrim : BSPhysObject _rotationalVelocity = OMV.Vector3.Zero; // Zero some other properties directly into the physics engine - BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); - BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); - BulletSimAPI.ClearForces2(BSBody.Ptr); + BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); + BulletSimAPI.ClearForces2(BSBody.ptr); } public override void LockAngularMotion(OMV.Vector3 axis) @@ -262,7 +268,7 @@ public sealed class BSPrim : BSPhysObject get { if (!Linkset.IsRoot(this)) // child prims move around based on their parent. Need to get the latest location - _position = BulletSimAPI.GetPosition2(BSBody.Ptr); + _position = BulletSimAPI.GetPosition2(BSBody.ptr); // don't do the GetObjectPosition for root elements because this function is called a zillion times // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, LocalID); @@ -274,7 +280,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); }); } } @@ -312,7 +318,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setForce", delegate() { DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); + BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); }); } } @@ -374,12 +380,15 @@ public sealed class BSPrim : BSPhysObject // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more public override void SetVolumeDetect(int param) { bool newValue = (param != 0); - _isVolumeDetect = newValue; - PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() + if (_isVolumeDetect != newValue) { - DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); - SetObjectDynamic(true); - }); + _isVolumeDetect = newValue; + PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() + { + DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); + SetObjectDynamic(true); + }); + } return; } @@ -390,7 +399,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() { DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); - BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity); + BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); }); } } @@ -414,7 +423,7 @@ public sealed class BSPrim : BSPhysObject if (!Linkset.IsRoot(this)) { // Children move around because tied to parent. Get a fresh value. - _orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr); + _orientation = BulletSimAPI.GetOrientation2(BSBody.ptr); } return _orientation; } @@ -425,7 +434,7 @@ public sealed class BSPrim : BSPhysObject { // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, LocalID); DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); }); } } @@ -436,12 +445,15 @@ public sealed class BSPrim : BSPhysObject public override bool IsPhysical { get { return _isPhysical; } set { - _isPhysical = value; - PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() + if (_isPhysical != value) { - DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); - SetObjectDynamic(true); - }); + _isPhysical = value; + PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() + { + DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); + SetObjectDynamic(true); + }); + } } } @@ -458,7 +470,7 @@ public sealed class BSPrim : BSPhysObject } // Make gravity work if the object is physical and not selected - // No locking here because only called when it is safe + // No locking here because only called when it is safe (called at taint-time). // There are four flags we're interested in: // IsStatic: Object does not move, otherwise the object has mass and moves // isSolid: other objects bounce off of this object @@ -481,11 +493,13 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); // Mangling all the physical properties requires the object to be out of the physical world - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); +#if !CSHARP_BODY_MANAGEMENT // 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); +#endif // !CSHARP_BODY_MANAGEMENT // Set up the object physicalness (does gravity and collisions move this object) MakeDynamic(IsStatic); @@ -493,15 +507,23 @@ public sealed class BSPrim : BSPhysObject // Arrange for collisions events if the simulator wants them EnableCollisions(SubscribedEvents()); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); +#if CSHARP_BODY_MANAGEMENT + // Make solid or not (do things bounce off or pass through this object). + MakeSolid(IsSolid); +#endif // CSHARP_BODY_MANAGEMENT + + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); + + // Rebuild its shape + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr); // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that // had been automatically disabled when the mass was set to zero. Linkset.Refresh(this); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3},collide={4},cf={5}", - LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", + LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); } // "Making dynamic" means changing to and from static. @@ -514,52 +536,52 @@ public sealed class BSPrim : BSPhysObject if (makeStatic) { // Become a Bullet 'static' object type - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement - BulletSimAPI.ClearAllForces2(BSBody.Ptr); + BulletSimAPI.ClearAllForces2(BSBody.ptr); // Center of mass is at the center of the object - BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.Ptr, _position, _orientation); + BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation); // Mass is zero which disables a bunch of physics stuff in Bullet - BulletSimAPI.SetMassProps2(BSBody.Ptr, 0f, OMV.Vector3.Zero); + BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); // There is no inertia in a static object - BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); + BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); // There can be special things needed for implementing linksets Linkset.MakeStatic(this); // The activation state is 'sleeping' so Bullet will not try to act on it - BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING); + BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); // BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.DISABLE_SIMULATION); } else { // Not a Bullet static object - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Set various physical properties so internal dynamic properties will get computed correctly as they are set - BulletSimAPI.SetFriction2(BSBody.Ptr, PhysicsScene.Params.defaultFriction); - BulletSimAPI.SetRestitution2(BSBody.Ptr, PhysicsScene.Params.defaultRestitution); + BulletSimAPI.SetFriction2(BSBody.ptr, PhysicsScene.Params.defaultFriction); + BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.defaultRestitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 - BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); - BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); - BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); // A dynamic object has mass - IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr); + IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass); - BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia); + BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); // Inertia is based on our new mass - BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); + BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); // Various values for simulation limits - BulletSimAPI.SetDamping2(BSBody.Ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); - BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, PhysicsScene.Params.deactivationTime); - BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); - BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, PhysicsScene.Params.contactProcessingThreshold); + BulletSimAPI.SetDamping2(BSBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); + BulletSimAPI.SetDeactivationTime2(BSBody.ptr, PhysicsScene.Params.deactivationTime); + BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); + BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); // There can be special things needed for implementing linksets Linkset.MakeDynamic(this); // Force activation of the object so Bullet will act on it. - BulletSimAPI.Activate2(BSBody.Ptr, true); + BulletSimAPI.Activate2(BSBody.ptr, true); } } @@ -569,8 +591,28 @@ 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) { -#if !CSHARP_BODY_MANAGEMENT - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.Ptr); +#if CSHARP_BODY_MANAGEMENT + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr); + if (makeSolid) + { + // Verify the previous code created the correct shape for this type of thing. + if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) + { + m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); + } + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + } + else + { + if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0) + { + m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); + } + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + } +#else + // If doing the body management in C#, all this logic is in CSShapeCollection.CreateObject(). + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr); if (makeSolid) { if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) @@ -618,11 +660,11 @@ public sealed class BSPrim : BSPhysObject { if (wantsCollisionEvents) { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } else { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } } @@ -683,7 +725,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(BSBody.ptr, _rotationalVelocity); }); } } @@ -702,7 +744,7 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav)); + BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); // BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); }); } @@ -767,7 +809,7 @@ public sealed class BSPrim : BSPhysObject } DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. - BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum); + BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); }); } @@ -1394,7 +1436,7 @@ public sealed class BSPrim : BSPhysObject } // Rebuild the geometry and object. // This is called when the shape changes so we need to recreate the mesh/hull. - // No locking here because this is done when the physics engine is not simulating + // No locking here because this is done when the physics engine is not simulating (taint-time). private void CreateGeomAndObject(bool forceRebuild) { #if CSHARP_BODY_MANAGEMENT @@ -1403,11 +1445,10 @@ public sealed class BSPrim : BSPhysObject // Create the correct physical representation for this type of object. // Updates BSBody and BSShape with the new information. - if (PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs)) - { - // Make sure the properties are set on the new object - UpdatePhysicalParameters(); - } + PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs); + + // Make sure the properties are set on the new object + UpdatePhysicalParameters(); #else // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, LocalID, forceRebuild); // Create the geometry that will make up the object diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 76da42d2d1..87c7b1b95d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -589,6 +589,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters { if (localID <= TerrainManager.HighestTerrainID) { + DetailLog("{0},BSScene.SendCollision,collideWithTerrain,id={1},with={2}", DetailLogZero, localID, collidingWith); return; // don't send collisions to the terrain } @@ -596,6 +597,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (!PhysObjects.TryGetValue(localID, out collider)) { // If the object that is colliding cannot be found, just ignore the collision. + DetailLog("{0},BSScene.SendCollision,colliderNotInObjectList,id={1},with={2}", DetailLogZero, localID, collidingWith); return; } @@ -604,7 +606,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters BSPhysObject collidee = null; PhysObjects.TryGetValue(collidingWith, out collidee); - // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); + DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 7470d23acb..6b906610d6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -38,8 +38,9 @@ public class BSShapeCollection : IDisposable { protected BSScene PhysicsScene { get; set; } - private Object m_shapeActivityLock = new Object(); + private Object m_collectionActivityLock = new Object(); + // Description of a Mesh private struct MeshDesc { public IntPtr Ptr; @@ -48,6 +49,8 @@ public class BSShapeCollection : IDisposable public IMesh meshData; } + // Description of a hull. + // Meshes and hulls have the same shape hash key but we only need hulls for efficient physical objects private struct HullDesc { public IntPtr Ptr; @@ -55,8 +58,17 @@ public class BSShapeCollection : IDisposable public DateTime lastReferenced; } + private struct BodyDesc + { + public IntPtr Ptr; + // Bodies are only used once so reference count is always either one or zero + public int referenceCount; + public DateTime lastReferenced; + } + private Dictionary Meshes = new Dictionary(); private Dictionary Hulls = new Dictionary(); + private Dictionary Bodies = new Dictionary(); public BSShapeCollection(BSScene physScene) { @@ -65,6 +77,7 @@ public class BSShapeCollection : IDisposable public void Dispose() { + // TODO!!!!!!!!! } // Called to update/change the body and shape for an object. @@ -76,40 +89,104 @@ public class BSShapeCollection : IDisposable { bool ret = false; - // Do we have the correct geometry for this type of object? - if (CreateGeom(forceRebuild, prim, shapeData, pbs)) + // This lock could probably be pushed down lower but building shouldn't take long + lock (m_collectionActivityLock) { + // Do we have the correct geometry for this type of object? + bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs); // If we had to select a new shape geometry for the object, // rebuild the body around it. - CreateObject(true, prim, PhysicsScene.World, prim.BSShape, shapeData); - ret = true; + bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData); + ret = newGeom || newBody; } + DetailLog("{0},BSShapeCollection.GetBodyAndShape,force-{1},ret={2},body={3},shape={4}", + prim.LocalID, forceRebuild, ret, prim.BSBody, prim.BSShape); return ret; } // Track another user of a body - public void ReferenceBody(BulletBody shape) + // We presume the caller has allocated the body. + // Bodies only have one user so the reference count is either 1 or 0. + public void ReferenceBody(BulletBody shape, bool atTaintTime) { - } + lock (m_collectionActivityLock) + { + BodyDesc bodyDesc; + if (Bodies.TryGetValue(shape.ID, out bodyDesc)) + { + bodyDesc.referenceCount++; + DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,ref={1}", shape.ID, bodyDesc.referenceCount); + } + else + { + bodyDesc.Ptr = shape.ptr; + bodyDesc.referenceCount = 1; + DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={1}", shape.ID, bodyDesc.referenceCount); + } + bodyDesc.lastReferenced = System.DateTime.Now; + Bodies[shape.ID] = bodyDesc; + } +} - // Release the usage of a body - public void DereferenceBody(BulletBody shape) + // Release the usage of a body. + // Not that this will also delete the body in BUllet if the body is now unused (reference count = 0). + public void DereferenceBody(BulletBody shape, bool inTaintTime) { + if (shape.ptr == IntPtr.Zero) + return; + + lock (m_collectionActivityLock) + { + BodyDesc bodyDesc; + if (Bodies.TryGetValue(shape.ID, out bodyDesc)) + { + bodyDesc.referenceCount--; + bodyDesc.lastReferenced = System.DateTime.Now; + Bodies[shape.ID] = bodyDesc; + DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", shape.ID, bodyDesc.referenceCount); + + if (bodyDesc.referenceCount == 0) + { + Bodies.Remove(shape.ID); + BSScene.TaintCallback removeOperation = delegate() + { + DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. Ptr={1:X}", shape.ID, shape.ptr); + // zero any reference to the shape so it is not freed when the body is deleted + BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, shape.ptr, IntPtr.Zero); + // It may have already been removed from the world in which case the next is a NOOP + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, shape.ptr); + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, shape.ptr); + }; + // If already in taint-time, do the operations now. Otherwise queue for later. + if (inTaintTime) + removeOperation(); + else + PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation); + } + } + else + { + DetailLog("{0},BSShapeCollection.DereferenceBody,DID NOT FIND BODY", shape.ID, bodyDesc.referenceCount); + } + } } // Track another user of the shape - public void ReferenceShape(BulletShape shape) + private bool ReferenceShape(BulletShape shape) { - ReferenceShape(shape, null); + return ReferenceShape(shape, null); } // Track the datastructures and use count for a shape. // When creating a hull, this is called first to reference the mesh // and then again to reference the hull. // Meshes and hulls for the same shape have the same hash key. - private void ReferenceShape(BulletShape shape, IMesh meshData) + // NOTE that native shapes are not added to the mesh list or removed. + // Returns 'true' if this is the initial reference to the shape. Otherwise reused. + private bool ReferenceShape(BulletShape shape, IMesh meshData) { + bool ret = false; switch (shape.type) { case ShapeData.PhysicsShapeType.SHAPE_MESH: @@ -118,14 +195,18 @@ public class BSShapeCollection : IDisposable { // There is an existing instance of this mesh. meshDesc.referenceCount++; + DetailLog("{0},BSShapeColliction.ReferenceShape,existingMesh,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey, meshDesc.referenceCount); } else { // This is a new reference to a mesh - meshDesc.Ptr = shape.Ptr; + meshDesc.Ptr = shape.ptr; meshDesc.meshData = meshData; meshDesc.referenceCount = 1; - + DetailLog("{0},BSShapeColliction.ReferenceShape,newMesh,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey, meshDesc.referenceCount); + ret = true; } meshDesc.lastReferenced = System.DateTime.Now; Meshes[shape.shapeKey] = meshDesc; @@ -136,41 +217,68 @@ public class BSShapeCollection : IDisposable { // There is an existing instance of this mesh. hullDesc.referenceCount++; + DetailLog("{0},BSShapeColliction.ReferenceShape,existingHull,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey, hullDesc.referenceCount); } else { - // This is a new reference to a mesh - hullDesc.Ptr = shape.Ptr; + // This is a new reference to a hull + hullDesc.Ptr = shape.ptr; hullDesc.referenceCount = 1; + DetailLog("{0},BSShapeColliction.ReferenceShape,newHull,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey, hullDesc.referenceCount); + ret = true; } hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; break; + case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: + break; default: + // Native shapes are not tracked and they don't go into any list break; } + return ret; } // Release the usage of a shape - public void DereferenceShape(BulletShape shape) + private void DereferenceShape(BulletShape shape, bool atTaintTime) { - switch (shape.type) + if (shape.ptr == IntPtr.Zero) + return; + + BSScene.TaintCallback dereferenceOperation = delegate() { - case ShapeData.PhysicsShapeType.SHAPE_HULL: - DereferenceHull(shape); - // Hulls also include a mesh - DereferenceMesh(shape); - break; - case ShapeData.PhysicsShapeType.SHAPE_MESH: - DereferenceMesh(shape); - break; - default: - break; - } + switch (shape.type) + { + case ShapeData.PhysicsShapeType.SHAPE_HULL: + DereferenceHull(shape); + // Hulls also include a mesh + DereferenceMesh(shape); + break; + case ShapeData.PhysicsShapeType.SHAPE_MESH: + DereferenceMesh(shape); + break; + case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: + break; + default: + // Native shapes are not tracked and are released immediately + if (shape.ptr != IntPtr.Zero & shape.isNativeShape) + { + BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); + } + break; + } + }; + if (atTaintTime) + dereferenceOperation(); + else + PhysicsScene.TaintedObject("BSShapeCollection.DereferenceShape", dereferenceOperation); } // Count down the reference count for a mesh shape + // Called at taint-time. private void DereferenceMesh(BulletShape shape) { MeshDesc meshDesc; @@ -180,10 +288,14 @@ public class BSShapeCollection : IDisposable // TODO: release the Bullet storage meshDesc.lastReferenced = System.DateTime.Now; Meshes[shape.shapeKey] = meshDesc; + DetailLog("{0},BSShapeColliction.DereferenceMesh,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey, meshDesc.referenceCount); + } } // Count down the reference count for a hull shape + // Called at taint-time. private void DereferenceHull(BulletShape shape) { HullDesc hullDesc; @@ -193,6 +305,8 @@ public class BSShapeCollection : IDisposable // TODO: release the Bullet storage (aging old entries?) hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; + DetailLog("{0},BSShapeColliction.DereferenceHull,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey, hullDesc.referenceCount); } } @@ -210,10 +324,6 @@ public class BSShapeCollection : IDisposable BulletShape newShape = new BulletShape(IntPtr.Zero); - // If the object is dynamic, it must have a hull shape - if (prim.IsPhysical) - nativeShapePossible = false; - // If the prim attributes are simple, this could be a simple Bullet native shape if (nativeShapePossible && ((pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) @@ -230,8 +340,10 @@ public class BSShapeCollection : IDisposable haveShape = true; if (forceRebuild || (prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) { - DetailLog("{0},BSShapeCollection.CreateGeom,sphere (force={1}", prim.LocalID, forceRebuild); - newShape = AddNativeShapeToPrim(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE); + newShape = AddNativeShapeToPrim( + prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE); + DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", + prim.LocalID, forceRebuild,prim.BSShape); ret = true; } @@ -242,71 +354,87 @@ public class BSShapeCollection : IDisposable haveShape = true; if (forceRebuild || (prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX)) { - DetailLog("{0},BSShapeCollection.CreateGeom,box (force={1})", prim.LocalID, forceRebuild); - newShape = AddNativeShapeToPrim(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX); + newShape = AddNativeShapeToPrim( + prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); + DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", + prim.LocalID, forceRebuild,prim.BSShape); ret = true; } } } - // If a simple shape isn't happening, create a mesh and possibly a hull + // If a simple shape is not happening, create a mesh and possibly a hull + // Note that if it's a native shape, the check for physical/non-physical is not + // made. Native shapes are best used in either case. if (!haveShape) { if (prim.IsPhysical) { - if (forceRebuild || !Hulls.ContainsKey(prim.BSShape.shapeKey)) + if (forceRebuild || !Hulls.ContainsKey(shapeData.HullKey)) { // physical objects require a hull for interaction. - // This also creates the mesh if it doesn't already exist + // This also creates the mesh if it doesn't already exist. ret = CreateGeomHull(prim, shapeData, pbs); } + else + { + prim.BSShape = new BulletShape(Hulls[shapeData.HullKey].Ptr, + ShapeData.PhysicsShapeType.SHAPE_HULL); + prim.BSShape.shapeKey = shapeData.HullKey; + // Another user of this shape. + ReferenceShape(prim.BSShape); + ret = true; + } } else { if (forceRebuild || !Meshes.ContainsKey(prim.BSShape.shapeKey)) { // Static (non-physical) objects only need a mesh for bumping into + // Returning 'true' means prim.BShape was changed. ret = CreateGeomMesh(prim, shapeData, pbs); } + else + { + prim.BSShape = new BulletShape(Hulls[shapeData.MeshKey].Ptr, + ShapeData.PhysicsShapeType.SHAPE_MESH); + prim.BSShape.shapeKey = shapeData.MeshKey; + ReferenceShape(prim.BSShape); + ret = true; + } } } return ret; } - private BulletShape AddNativeShapeToPrim(BSPrim prim, ShapeData shapeData, ShapeData.PhysicsShapeType shapeType) + // Creates a native shape and assignes it to prim.BSShape + private BulletShape AddNativeShapeToPrim( + BSPrim prim, ShapeData shapeData, ShapeData.PhysicsShapeType shapeType, + ShapeData.FixedShapeKey shapeKey) { BulletShape newShape; // Bullet native objects are scaled by the Bullet engine so pass the size in prim.Scale = shapeData.Size; + shapeData.Type = shapeType; + shapeData.Scale = prim.Scale; // release any previous shape - DereferenceShape(prim.BSShape); + DereferenceShape(prim.BSShape, true); + + // Shape of this discriptioin is not allocated. Create new. + newShape = new BulletShape( + BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); + newShape.shapeKey = (ulong)shapeKey; + newShape.isNativeShape = true; + + // Don't to a 'ReferenceShape()' here because native shapes are not tracked. - MeshDesc existingShapeDesc; - if (Meshes.TryGetValue(shapeData.MeshKey, out existingShapeDesc)) - { - // If there is an existing allocated shape, use it - newShape = new BulletShape(existingShapeDesc.Ptr, shapeType); - } - else - { - // Shape of this discriptioin is not allocated. Create new. - newShape = new BulletShape( - BulletSimAPI.BuildNativeShape2(PhysicsScene.World.Ptr, - (float)shapeType, - PhysicsScene.Params.collisionMargin, - prim.Scale), - shapeType); - } - newShape.shapeKey = shapeData.MeshKey; - ReferenceShape(newShape); prim.BSShape = newShape; return newShape; } - // No locking here because this is done when we know physics is not simulating - // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). + // Returns 'true' of a mesh was actually rebuild. // Called at taint-time! private bool CreateGeomMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) { @@ -322,7 +450,6 @@ public class BSShapeCollection : IDisposable lod = PhysicsScene.MeshMegaPrimLOD; ulong newMeshKey = (ulong)pbs.GetMeshKey(shapeData.Size, lod); - // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, LocalID, _meshKey, newMeshKey); // if this new shape is the same as last time, don't recreate the mesh if (prim.BSShape.shapeKey == newMeshKey) return false; @@ -330,7 +457,7 @@ public class BSShapeCollection : IDisposable DetailLog("{0},BSShapeCollection.CreateGeomMesh,create,key={1}", prim.LocalID, newMeshKey); // Since we're recreating new, get rid of the reference to the previous shape - DereferenceShape(prim.BSShape); + DereferenceShape(prim.BSShape, true); IMesh meshData = null; IntPtr meshPtr; @@ -360,7 +487,7 @@ public class BSShapeCollection : IDisposable // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); - meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.Ptr, + meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, indices.GetLength(0), indices, vertices.Count, verticesAsFloats); } newShape = new BulletShape(meshPtr, ShapeData.PhysicsShapeType.SHAPE_MESH); @@ -374,26 +501,29 @@ public class BSShapeCollection : IDisposable return true; // 'true' means a new shape has been added to this prim } - // No locking here because this is done when we know physics is not simulating // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). List m_hulls; private bool CreateGeomHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) { BulletShape newShape; + // Level of detail for the mesh can be different for sculpties and regular meshes. float lod = pbs.SculptEntry ? PhysicsScene.SculptLOD : PhysicsScene.MeshLOD; + ulong newHullKey = (ulong)pbs.GetMeshKey(shapeData.Size, lod); - // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, LocalID, _hullKey, newHullKey); // if the hull hasn't changed, don't rebuild it if (newHullKey == prim.BSShape.shapeKey) return false; DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", prim.LocalID, newHullKey, newHullKey); - // remove references to any previous shape - DereferenceShape(prim.BSShape); + // Remove references to the previous shape. Also removes reference to underlying mesh. + DereferenceShape(prim.BSShape, true); - // Make sure the underlying mesh exists and is correct + // Do not let the mesh dereference itself again. Was done in the above DerefereceShape(). + prim.BSShape.type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + + // Make sure the underlying mesh exists and is correct. // Since we're in the hull code, we know CreateGeomMesh() will not create a native shape. CreateGeomMesh(prim, shapeData, pbs); MeshDesc meshDesc = Meshes[newHullKey]; @@ -402,10 +532,12 @@ public class BSShapeCollection : IDisposable HullDesc hullDesc; if (Hulls.TryGetValue(newHullKey, out hullDesc)) { + // If the hull shape already is created, just use it. hullPtr = hullDesc.Ptr; } else { + // Build a new hull in the physical world int[] indices = meshDesc.meshData.getIndexListAsInt(); List vertices = meshDesc.meshData.getVertexList(); @@ -485,63 +617,85 @@ public class BSShapeCollection : IDisposable } // create the hull data structure in Bullet // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, LocalID, _hullKey, hullCount); - hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.Ptr, hullCount, convHulls); + hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls); } + newShape = new BulletShape(hullPtr, ShapeData.PhysicsShapeType.SHAPE_HULL); newShape.shapeKey = newHullKey; + newShape.meshPtr = meshDesc.Ptr; ReferenceShape(newShape); - // meshes are already scaled by the meshmerizer + // meshes and hulls are already scaled by the meshmerizer prim.Scale = new OMV.Vector3(1f, 1f, 1f); prim.BSShape = newShape; return true; // 'true' means a new shape has been added to this prim } // Callback from convex hull creater with a newly created hull. - // Just add it to the collection of hulls for this shape. + // Just add it to our collection of hulls for this shape. private void HullReturn(ConvexResult result) { m_hulls.Add(result); return; } - // Create an object in Bullet if it has not already been created - // No locking here because this is done when the physics engine is not simulating + // Create an object in Bullet if it has not already been created. + // Updates prim.BSBody with the information about the new body if one is created. // Returns 'true' if an object was actually created. - private bool CreateObject(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData) + // Called at taint-time. + private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData) { - // the mesh or hull must have already been created in Bullet - // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, LocalID, shape.Type); + bool ret = false; - DereferenceBody(prim.BSBody); + // the mesh, hull or native shape must have already been created in Bullet + bool mustRebuild = (prim.BSBody.ptr == IntPtr.Zero); - BulletBody aBody; - IntPtr bodyPtr = IntPtr.Zero; - if (prim.IsSolid) + // If there is an existing body, verify it's of an acceptable type. + // If not a solid object, body is a GhostObject. Otherwise a RigidBody. + if (!mustRebuild) { - bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.Ptr, shape.Ptr, shapeData.Position, shapeData.Rotation); + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.BSBody.ptr); + if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY + || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) + { + // If the collisionObject is not the correct type for solidness, rebuild what's there + mustRebuild = true; + } + } - else + + if (mustRebuild) { - bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.Ptr, shape.Ptr, shapeData.Position, shapeData.Rotation); + DereferenceBody(prim.BSBody, true); + + BulletBody aBody; + IntPtr bodyPtr = IntPtr.Zero; + if (prim.IsSolid) + { + bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, shapeData.Position, shapeData.Rotation); + DetailLog("{0},BSShapeCollection.CreateObject,mesh,ptr={1:X}", prim.LocalID, bodyPtr); + } + else + { + bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, shapeData.Position, shapeData.Rotation); + DetailLog("{0},BSShapeCollection.CreateObject,ghost,ptr={1:X}", prim.LocalID, bodyPtr); + } + aBody = new BulletBody(shapeData.ID, bodyPtr); + + ReferenceBody(aBody, true); + + prim.BSBody = aBody; + + ret = true; } - aBody = new BulletBody(shapeData.ID, bodyPtr); - ReferenceBody(aBody); - - prim.BSBody = aBody; - return true; + return ret; } private void DetailLog(string msg, params Object[] args) { PhysicsScene.PhysicsLogging.Write(msg, args); } - - - - - } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index fb802e4d0e..093d2a43e7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -111,8 +111,8 @@ public class BSTerrainManager 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); + BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, Vector3.Zero, Quaternion.Identity)); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE); Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION); @@ -128,13 +128,13 @@ public class BSTerrainManager // Release all the terrain structures we might have allocated public void ReleaseGroundPlaneAndTerrain() { - if (m_groundPlane.Ptr != IntPtr.Zero) + if (m_groundPlane.ptr != IntPtr.Zero) { - if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, m_groundPlane.Ptr)) + if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) { - BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, m_groundPlane.Ptr); + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); } - m_groundPlane.Ptr = IntPtr.Zero; + m_groundPlane.ptr = IntPtr.Zero; } ReleaseTerrain(); @@ -145,9 +145,9 @@ public class BSTerrainManager { foreach (KeyValuePair kvp in m_heightMaps) { - if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, kvp.Value.terrainBody.Ptr)) + if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, kvp.Value.terrainBody.ptr)) { - BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, kvp.Value.terrainBody.Ptr); + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, kvp.Value.terrainBody.ptr); BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr); } } @@ -248,17 +248,17 @@ public class BSTerrainManager return; } - if (mapInfo.terrainBody.Ptr != IntPtr.Zero) + if (mapInfo.terrainBody.ptr != IntPtr.Zero) { // Updating an existing terrain. DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}", BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY); // Remove from the dynamics world because we're going to mangle this object - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); // Get rid of the old terrain - BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr); mapInfo.Ptr = IntPtr.Zero; @@ -289,7 +289,7 @@ public class BSTerrainManager BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ); mapInfo.ID = id; - mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.Ptr, mapInfo.ID, + mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, mapInfo.ID, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN); // The terrain object initial position is at the center of the object @@ -303,7 +303,7 @@ public class BSTerrainManager ShapeData.PhysicsShapeType.SHAPE_TERRAIN); mapInfo.terrainBody = new BulletBody(mapInfo.ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.Ptr, + BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.ptr, centerPos, Quaternion.Identity)); } @@ -311,22 +311,22 @@ public class BSTerrainManager m_heightMaps[terrainRegionBase] = mapInfo; // Set current terrain attributes - BulletSimAPI.SetFriction2(mapInfo.terrainBody.Ptr, PhysicsScene.Params.terrainFriction); - BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.Ptr, PhysicsScene.Params.terrainHitFraction); - BulletSimAPI.SetRestitution2(mapInfo.terrainBody.Ptr, PhysicsScene.Params.terrainRestitution); - BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + BulletSimAPI.SetFriction2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); + BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + BulletSimAPI.SetRestitution2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - BulletSimAPI.SetMassProps2(mapInfo.terrainBody.Ptr, 0f, Vector3.Zero); - BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.Ptr); + BulletSimAPI.SetMassProps2(mapInfo.terrainBody.ptr, 0f, Vector3.Zero); + BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.ptr); // Return the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); // redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); // Make sure the new shape is processed. - BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true); + BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true); m_terrainModified = true; }; @@ -361,7 +361,7 @@ public class BSTerrainManager DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y); // Create a new mapInfo that will be filled with the new info mapInfo = new BulletHeightMapInfo(id, heightMapX, - BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.Ptr, newTerrainID, + BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, newTerrainID, minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN)); // Put the unfilled heightmap info into the collection of same m_heightMaps.Add(terrainRegionBase, mapInfo); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 47875b0332..8480dd1be3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -40,14 +40,14 @@ public struct BulletSim { public BulletSim(uint worldId, BSScene bss, IntPtr xx) { + ptr = xx; worldID = worldId; scene = bss; - Ptr = xx; } + 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 scene; - public IntPtr Ptr; } // An allocated Bullet btRigidBody @@ -56,9 +56,9 @@ public struct BulletBody public BulletBody(uint id, IntPtr xx) { ID = id; - Ptr = xx; + ptr = xx; } - public IntPtr Ptr; + public IntPtr ptr; public uint ID; public override string ToString() { @@ -66,7 +66,7 @@ public struct BulletBody buff.Append(""); return buff.ToString(); } @@ -76,28 +76,39 @@ public struct BulletShape { public BulletShape(IntPtr xx) { - Ptr = xx; + ptr = xx; type=ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; shapeKey = 0; + isNativeShape = false; + meshPtr = IntPtr.Zero; } public BulletShape(IntPtr xx, ShapeData.PhysicsShapeType typ) { - Ptr = xx; + ptr = xx; type = typ; shapeKey = 0; + isNativeShape = false; + meshPtr = IntPtr.Zero; } - public IntPtr Ptr; + public IntPtr ptr; public ShapeData.PhysicsShapeType type; public ulong shapeKey; + public bool isNativeShape; + // Hulls have an underlying mesh. A pointer to it is hidden here. + public IntPtr meshPtr; public override string ToString() { StringBuilder buff = new StringBuilder(); buff.Append(""); return buff.ToString(); } @@ -314,10 +325,10 @@ public enum CollisionFlags : uint CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, // Following used by BulletSim to control collisions BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, - BS_VOLUME_DETECT_OBJECT = 1 << 11, - BS_PHANTOM_OBJECT = 1 << 12, - BS_PHYSICAL_OBJECT = 1 << 13, - BS_TERRAIN_OBJECT = 1 << 14, + // BS_VOLUME_DETECT_OBJECT = 1 << 11, + // BS_PHANTOM_OBJECT = 1 << 12, + // BS_PHYSICAL_OBJECT = 1 << 13, + // BS_TERRAIN_OBJECT = 1 << 14, BS_NONE = 0, BS_ALL = 0xFFFFFFFF, @@ -326,9 +337,9 @@ public enum CollisionFlags : uint BS_ACTIVE = CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE - | BS_VOLUME_DETECT_OBJECT - | BS_PHANTOM_OBJECT - | BS_PHYSICAL_OBJECT, + // | BS_VOLUME_DETECT_OBJECT + // | BS_PHANTOM_OBJECT + // | BS_PHYSICAL_OBJECT, }; // Values for collisions groups and masks @@ -552,8 +563,7 @@ public static extern IntPtr CreateHullShape2(IntPtr world, public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildNativeShape2(IntPtr world, - float shapeType, float collisionMargin, Vector3 scale); +public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool IsNativeShape2(IntPtr shape); @@ -567,6 +577,9 @@ public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShap [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); + [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo);