diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 526dbadd97..57d5726888 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -28,7 +28,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using OpenMetaverse; +using OMV = OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; @@ -39,25 +39,24 @@ public class BSCharacter : BSPhysObject private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS CHAR]"; - public BSScene Scene { get; private set; } private String _avName; // private bool _stopped; - private Vector3 _size; - private Vector3 _scale; + private OMV.Vector3 _size; + private OMV.Vector3 _scale; private PrimitiveBaseShape _pbs; private uint _localID = 0; private bool _grabbed; private bool _selected; - private Vector3 _position; + private OMV.Vector3 _position; private float _mass; public float _density; public float _avatarVolume; - private Vector3 _force; - private Vector3 _velocity; - private Vector3 _torque; + private OMV.Vector3 _force; + private OMV.Vector3 _velocity; + private OMV.Vector3 _torque; private float _collisionScore; - private Vector3 _acceleration; - private Quaternion _orientation; + private OMV.Vector3 _acceleration; + private OMV.Quaternion _orientation; private int _physicsActorType; private bool _isPhysical; private bool _flying; @@ -69,18 +68,14 @@ public class BSCharacter : BSPhysObject private long _collidingGroundStep; private bool _collidingObj; private bool _floatOnWater; - private Vector3 _rotationalVelocity; + private OMV.Vector3 _rotationalVelocity; private bool _kinematic; private float _buoyancy; - public override BulletBody BSBody { get; set; } - public override BulletShape BSShape { get; set; } - public override BSLinkset Linkset { get; set; } - private int _subscribedEventsMs = 0; private int _nextCollisionOkTime = 0; - private Vector3 _PIDTarget; + private OMV.Vector3 _PIDTarget; private bool _usePID; private float _PIDTau; private bool _useHoverPID; @@ -88,26 +83,24 @@ public class BSCharacter : BSPhysObject private PIDHoverType _PIDHoverType; private float _PIDHoverTao; - public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying) + public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) { + base.BaseInitialize(parent_scene); _localID = localID; _avName = avName; - Scene = parent_scene; _physicsActorType = (int)ActorTypes.Agent; _position = pos; _size = size; _flying = isFlying; - _orientation = Quaternion.Identity; - _velocity = Vector3.Zero; + _orientation = OMV.Quaternion.Identity; + _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); // The dimensions of the avatar capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. - _scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z); - _density = Scene.Params.avatarDensity; + _scale = new OMV.Vector3(PhysicsScene.Params.avatarCapsuleRadius, PhysicsScene.Params.avatarCapsuleRadius, size.Z); + _density = PhysicsScene.Params.avatarDensity; ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale - Linkset = new BSLinkset(Scene, this); - ShapeData shapeData = new ShapeData(); shapeData.ID = _localID; shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; @@ -118,19 +111,19 @@ public class BSCharacter : BSPhysObject shapeData.Mass = _mass; shapeData.Buoyancy = _buoyancy; shapeData.Static = ShapeData.numericFalse; - shapeData.Friction = Scene.Params.avatarFriction; - shapeData.Restitution = Scene.Params.avatarRestitution; + shapeData.Friction = PhysicsScene.Params.avatarFriction; + shapeData.Restitution = PhysicsScene.Params.avatarRestitution; // do actual create at taint time - Scene.TaintedObject("BSCharacter.create", delegate() + PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create", _localID); - BulletSimAPI.CreateObject(Scene.WorldID, shapeData); + BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData); // Set the buoyancy for flying. This will be refactored when all the settings happen in C# - BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); + BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); - BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID)); + BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID)); }); return; @@ -140,9 +133,9 @@ public class BSCharacter : BSPhysObject public override void Destroy() { DetailLog("{0},BSCharacter.Destroy", LocalID); - Scene.TaintedObject("BSCharacter.destroy", delegate() + PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() { - BulletSimAPI.DestroyObject(Scene.WorldID, _localID); + BulletSimAPI.DestroyObject(PhysicsScene.WorldID, _localID); }); } @@ -154,11 +147,11 @@ public class BSCharacter : BSPhysObject public override bool Stopped { get { return false; } } - public override Vector3 Size { + public override OMV.Vector3 Size { get { // Avatar capsule size is kept in the scale parameter. - return new Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z); + return new OMV.Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z); } set { @@ -171,9 +164,9 @@ public class BSCharacter : BSPhysObject ComputeAvatarVolumeAndMass(); - Scene.TaintedObject("BSCharacter.setSize", delegate() + PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { - BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true); + BulletSimAPI.SetObjectScaleMass(PhysicsScene.WorldID, LocalID, _scale, _mass, true); }); } @@ -198,9 +191,27 @@ public class BSCharacter : BSPhysObject public override void CrossingFailure() { return; } public override void link(PhysicsActor obj) { return; } public override void delink() { return; } - public override void LockAngularMotion(Vector3 axis) { return; } - public override Vector3 Position { + // Set motion values to zero. + // Do it to the properties so the values get set in the physics engine. + // Push the setting of the values to the viewer. + // Called at taint time! + public override void ZeroMotion() + { + _velocity = OMV.Vector3.Zero; + _acceleration = OMV.Vector3.Zero; + _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); + } + + public override void LockAngularMotion(OMV.Vector3 axis) { return; } + + public override OMV.Vector3 Position { get { // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); return _position; @@ -209,10 +220,10 @@ public class BSCharacter : BSPhysObject _position = value; PositionSanityCheck(); - Scene.TaintedObject("BSCharacter.setPosition", delegate() + PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() { DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation); + BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, _localID, _position, _orientation); }); } } @@ -225,7 +236,7 @@ public class BSCharacter : BSPhysObject bool ret = false; // If below the ground, move the avatar up - float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); if (Position.Z < terrainHeight) { DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); @@ -247,10 +258,10 @@ public class BSCharacter : BSPhysObject { // The new position value must be pushed into the physics engine but we can't // just assign to "Position" because of potential call loops. - Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate() + PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", delegate() { DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation); + BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, _localID, _position, _orientation); }); ret = true; } @@ -266,15 +277,15 @@ public class BSCharacter : BSPhysObject // used when we only want this prim's mass and not the linkset thing public override float MassRaw { get {return _mass; } } - public override Vector3 Force { + public override OMV.Vector3 Force { get { return _force; } set { _force = value; // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); - Scene.TaintedObject("BSCharacter.SetForce", delegate() + PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() { DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); - BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force); + BulletSimAPI.SetObjectForce(PhysicsScene.WorldID, LocalID, _force); }); } } @@ -284,28 +295,28 @@ public class BSCharacter : BSPhysObject set { return; } } public override void VehicleFloatParam(int param, float value) { } - public override void VehicleVectorParam(int param, Vector3 value) {} - public override void VehicleRotationParam(int param, Quaternion rotation) { } + public override void VehicleVectorParam(int param, OMV.Vector3 value) {} + public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { } public override void VehicleFlags(int param, bool remove) { } // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more public override void SetVolumeDetect(int param) { return; } - public override Vector3 GeometricCenter { get { return Vector3.Zero; } } - public override Vector3 CenterOfMass { get { return Vector3.Zero; } } - public override Vector3 Velocity { + public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } + public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } + public override OMV.Vector3 Velocity { get { return _velocity; } set { _velocity = value; // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); - Scene.TaintedObject("BSCharacter.setVelocity", delegate() + PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() { DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); - BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity); + BulletSimAPI.SetObjectVelocity(PhysicsScene.WorldID, _localID, _velocity); }); } } - public override Vector3 Torque { + public override OMV.Vector3 Torque { get { return _torque; } set { _torque = value; } @@ -315,19 +326,19 @@ public class BSCharacter : BSPhysObject set { _collisionScore = value; } } - public override Vector3 Acceleration { + public override OMV.Vector3 Acceleration { get { return _acceleration; } set { _acceleration = value; } } - public override Quaternion Orientation { + public override OMV.Quaternion Orientation { get { return _orientation; } set { _orientation = value; // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); - Scene.TaintedObject("BSCharacter.setOrientation", delegate() + PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() { // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); - BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation); + BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, _localID, _position, _orientation); }); } } @@ -364,11 +375,11 @@ public class BSCharacter : BSPhysObject set { _throttleUpdates = value; } } public override bool IsColliding { - get { return (_collidingStep == Scene.SimulationStep); } + get { return (_collidingStep == PhysicsScene.SimulationStep); } set { _isColliding = value; } } public override bool CollidingGround { - get { return (_collidingGroundStep == Scene.SimulationStep); } + get { return (_collidingGroundStep == PhysicsScene.SimulationStep); } set { _collidingGround = value; } } public override bool CollidingObj { @@ -378,7 +389,7 @@ public class BSCharacter : BSPhysObject public override bool FloatOnWater { set { _floatOnWater = value; } } - public override Vector3 RotationalVelocity { + public override OMV.Vector3 RotationalVelocity { get { return _rotationalVelocity; } set { _rotationalVelocity = value; } } @@ -390,16 +401,16 @@ public class BSCharacter : BSPhysObject public override float Buoyancy { get { return _buoyancy; } set { _buoyancy = value; - Scene.TaintedObject("BSCharacter.setBuoyancy", delegate() + PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() { DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); + BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); }); } } // Used for MoveTo - public override Vector3 PIDTarget { + public override OMV.Vector3 PIDTarget { set { _PIDTarget = value; } } public override bool PIDActive { @@ -425,19 +436,19 @@ public class BSCharacter : BSPhysObject } // For RotLookAt - public override Quaternion APIDTarget { set { return; } } + public override OMV.Quaternion APIDTarget { set { return; } } public override bool APIDActive { set { return; } } public override float APIDStrength { set { return; } } public override float APIDDamping { set { return; } } - public override void AddForce(Vector3 force, bool pushforce) { + public override void AddForce(OMV.Vector3 force, bool pushforce) { if (force.IsFinite()) { _force.X += force.X; _force.Y += force.Y; _force.Z += force.Z; // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); - Scene.TaintedObject("BSCharacter.AddForce", delegate() + PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() { DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); @@ -450,42 +461,9 @@ public class BSCharacter : BSPhysObject //m_lastUpdateSent = false; } - public override void AddAngularForce(Vector3 force, bool pushforce) { + public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { } - public override void SetMomentum(Vector3 momentum) { - } - - // Turn on collision events at a rate no faster than one every the given milliseconds - public override void SubscribeEvents(int ms) { - _subscribedEventsMs = ms; - if (ms > 0) - { - // make sure first collision happens - _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; - - Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate() - { - BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - }); - } - } - - public override void ZeroMotion() - { - return; - } - - // Stop collision events - public override void UnSubscribeEvents() { - _subscribedEventsMs = 0; - Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() - { - BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - }); - } - // Return 'true' if someone has subscribed to events - public override bool SubscribedEvents() { - return (_subscribedEventsMs > 0); + public override void SetMomentum(OMV.Vector3 momentum) { } // set _avatarVolume and _mass based on capsule size, _density and _scale @@ -520,67 +498,15 @@ public class BSCharacter : BSPhysObject // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. PositionSanityCheck2(); - float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug + float heightHere = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere); } - // Called by the scene when a collision with this object is reported - // The collision, if it should be reported to the character, is placed in a collection - // that will later be sent to the simulator when SendCollisions() is called. - CollisionEventUpdate collisionCollection = null; - public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) - { - bool ret = false; - - // The following makes IsColliding() and IsCollidingGround() work - _collidingStep = Scene.SimulationStep; - if (collidingWith <= Scene.TerrainManager.HighestTerrainID) - { - _collidingGroundStep = Scene.SimulationStep; - } - // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); - - // throttle collisions to the rate specified in the subscription - if (SubscribedEvents()) { - int nowTime = Scene.SimulationNowTime; - if (nowTime >= _nextCollisionOkTime) { - _nextCollisionOkTime = nowTime + _subscribedEventsMs; - - if (collisionCollection == null) - collisionCollection = new CollisionEventUpdate(); - collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); - ret = true; - } - } - return ret; - } - - public override void SendCollisions() - { - /* - if (collisionCollection != null && collisionCollection.Count > 0) - { - base.SendCollisionUpdate(collisionCollection); - collisionCollection = null; - } - */ - // Kludge to make a collision call even if there are no collisions. - // This causes the avatar animation to get updated. - if (collisionCollection == null) - collisionCollection = new CollisionEventUpdate(); - base.SendCollisionUpdate(collisionCollection); - // If there were any collisions in the collection, make sure we don't use the - // same instance next time. - if (collisionCollection.Count > 0) - collisionCollection = null; - // End kludge - } - // Invoke the detailed logger and output something if it's enabled. private void DetailLog(string msg, params Object[] args) { - Scene.PhysicsLogging.Write(msg, args); + PhysicsScene.PhysicsLogging.Write(msg, args); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 61006f07d6..2da2331127 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -539,7 +539,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // add Gravity and Buoyancy // There is some gravity, make a gravity force vector that is applied after object velocity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy)); + Vector3 grav = m_prim.PhysicsScene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy)); /* * RA: Not sure why one would do this @@ -552,7 +552,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); // If below the terrain, move us above the ground a little. - float terrainHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos); + float terrainHeight = m_prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. // Vector3 rotatedSize = m_prim.Size * m_prim.Orientation; @@ -570,7 +570,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = m_prim.Scene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; + m_VhoverTargetHeight = m_prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { @@ -849,8 +849,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Invoke the detailed logger and output something if it's enabled. private void VDetailLog(string msg, params Object[] args) { - if (m_prim.Scene.VehicleLoggingEnabled) - m_prim.Scene.PhysicsLogging.Write(msg, args); + if (m_prim.PhysicsScene.VehicleLoggingEnabled) + m_prim.PhysicsScene.PhysicsLogging.Write(msg, args); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 7e784ebb83..005a758b0a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -36,11 +36,9 @@ public class BSLinkset { private static string LogHeader = "[BULLETSIM LINKSET]"; - private BSPhysObject m_linksetRoot; - public BSPhysObject LinksetRoot { get { return m_linksetRoot; } } + public BSPhysObject LinksetRoot { get; protected set; } - private BSScene m_physicsScene; - public BSScene PhysicsScene { get { return m_physicsScene; } } + public BSScene PhysicsScene { get; private set; } static int m_nextLinksetID = 1; public int LinksetID { get; private set; } @@ -81,8 +79,8 @@ public class BSLinkset // We create LOTS of linksets. if (m_nextLinksetID < 0) m_nextLinksetID = 1; - m_physicsScene = scene; - m_linksetRoot = parent; + PhysicsScene = scene; + LinksetRoot = parent; m_children = new List(); m_mass = parent.MassRaw; } @@ -131,7 +129,7 @@ public class BSLinkset // Return 'true' if the passed object is the root object of this linkset public bool IsRoot(BSPhysObject requestor) { - return (requestor.LocalID == m_linksetRoot.LocalID); + return (requestor.LocalID == LinksetRoot.LocalID); } public int NumberOfChildren { get { return m_children.Count; } } @@ -159,7 +157,7 @@ public class BSLinkset private float ComputeLinksetMass() { - float mass = m_linksetRoot.MassRaw; + float mass = LinksetRoot.MassRaw; foreach (BSPhysObject bp in m_children) { mass += bp.MassRaw; @@ -169,8 +167,8 @@ public class BSLinkset private OMV.Vector3 ComputeLinksetCenterOfMass() { - OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw; - float totalMass = m_linksetRoot.MassRaw; + OMV.Vector3 com = LinksetRoot.Position * LinksetRoot.MassRaw; + float totalMass = LinksetRoot.MassRaw; lock (m_linksetActivityLock) { @@ -188,7 +186,7 @@ public class BSLinkset private OMV.Vector3 ComputeLinksetGeometricCenter() { - OMV.Vector3 com = m_linksetRoot.Position; + OMV.Vector3 com = LinksetRoot.Position; lock (m_linksetActivityLock) { @@ -256,7 +254,7 @@ public class BSLinkset foreach (BSPhysObject child in m_children) { BSConstraint constrain; - if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) + if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) { // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); @@ -306,9 +304,9 @@ public class BSLinkset BSPhysObject rootx = LinksetRoot; // capture the root as of now BSPhysObject childx = child; - m_physicsScene.TaintedObject("AddChildToLinkset", delegate() + PhysicsScene.TaintedObject("AddChildToLinkset", delegate() { - DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); + DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child }); } @@ -322,7 +320,7 @@ public class BSLinkset // has to be updated also (like pointer to prim's parent). private void RemoveChildFromOtherLinkset(BSPhysObject pchild) { - pchild.Linkset = new BSLinkset(m_physicsScene, pchild); + pchild.Linkset = new BSLinkset(PhysicsScene, pchild); RemoveChildFromLinkset(pchild); } @@ -334,9 +332,9 @@ public class BSLinkset { BSPhysObject rootx = LinksetRoot; // capture the root as of now BSPhysObject childx = child; - m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() + PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() { - DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); + DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); PhysicallyUnlinkAChildFromRoot(rootx, childx); RecomputeLinksetConstraintVariables(); @@ -370,7 +368,7 @@ public class BSLinkset DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); BS6DofConstraint constrain = new BS6DofConstraint( - m_physicsScene.World, rootPrim.BSBody, childPrim.BSBody, + PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true @@ -408,7 +406,7 @@ public class BSLinkset // ================================================================================== */ - m_physicsScene.Constraints.AddConstraint(constrain); + PhysicsScene.Constraints.AddConstraint(constrain); // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); @@ -435,7 +433,7 @@ public class BSLinkset DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); // Find the constraint for this link and get rid of it from the overall collection and from my list - m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); + PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); // Make the child refresh its location BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr); @@ -447,13 +445,13 @@ public class BSLinkset { DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); - m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); + PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); } // Invoke the detailed logger and output something if it's enabled. private void DetailLog(string msg, params Object[] args) { - m_physicsScene.PhysicsLogging.Write(msg, args); + PhysicsScene.PhysicsLogging.Write(msg, args); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 3fe71e1003..242aa80024 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -39,26 +39,150 @@ namespace OpenSim.Region.Physics.BulletSPlugin // unless the difference is significant. public abstract class BSPhysObject : PhysicsActor { - public abstract BSLinkset Linkset { get; set; } + protected void BaseInitialize(BSScene parentScene) + { + PhysicsScene = parentScene; + Linkset = new BSLinkset(PhysicsScene, this); - public abstract bool Collide(uint collidingWith, BSPhysObject collidee, - OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); - public abstract void SendCollisions(); + CollisionCollection = new CollisionEventUpdate(); + SubscribedEventsMs = 0; + CollidingStep = 0; + CollidingGroundStep = 0; + } - // Return the object mass without calculating it or side effects + public BSScene PhysicsScene { get; protected set; } + + public BSLinkset Linkset { get; set; } + + // Return the object mass without calculating it or having side effects public abstract float MassRaw { get; } // Reference to the physical body (btCollisionObject) of this object - public abstract BulletBody BSBody { get; set; } + public BulletBody BSBody { get; protected set; } // Reference to the physical shape (btCollisionShape) of this object - public abstract BulletShape BSShape { get; set; } + public BulletShape BSShape { get; protected set; } + // Stop all physical motion. public abstract void ZeroMotion(); + // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured. public virtual void StepVehicle(float timeStep) { } + // Update the physical location and motion of the object. Called with data from Bullet. public abstract void UpdateProperties(EntityProperties entprop); + // Tell the object to clean up. public abstract void Destroy(); + + #region Collisions + + // Requested number of milliseconds between collision events. Zero means disabled. + protected int SubscribedEventsMs { get; set; } + // Given subscription, the time that a collision may be passed up + protected int NextCollisionOkTime { get; set; } + // The simulation step that last had a collision + protected long CollidingStep { get; set; } + // The simulation step that last had a collision with the ground + protected long CollidingGroundStep { get; set; } + // The collision flags we think are set in Bullet + protected CollisionFlags CurrentCollisionFlags { get; set; } + + // The collisions that have been collected this tick + protected CollisionEventUpdate CollisionCollection; + + // The simulation step is telling this object about a collision. + // Return 'true' if a collision was processed and should be sent up. + // Called at taint time from within the Step() function + public virtual bool Collide(uint collidingWith, BSPhysObject collidee, + OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + { + bool ret = false; + + // The following lines make IsColliding() and IsCollidingGround() work + CollidingStep = PhysicsScene.SimulationStep; + if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) + { + CollidingGroundStep = PhysicsScene.SimulationStep; + } + + // prims in the same linkset cannot collide with each other + if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) + { + return ret; + } + + PhysicsScene.PhysicsLogging.Write("{0},BSPhysObject.Collison,call,with={1}", LocalID, collidingWith); + + // if someone has subscribed for collision events.... + if (SubscribedEvents()) { + CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + PhysicsScene.PhysicsLogging.Write("{0},BSPhysObject.Collison.AddCollider,call,with={1},point={2},normal={3},depth={4},next={5}", + LocalID, collidingWith, contactPoint, contactNormal, pentrationDepth, NextCollisionOkTime.ToString("yyyyMMddHHmmssfff")); + ret = true; + } + return ret; + } + + // Routine to send the collected collisions into the simulator. + // Also handles removal of this from the collection of objects with collisions if + // there are no collisions from this object. Mechanism is create one last + // collision event to make collision_end work. + public virtual void SendCollisions() + { + // throttle the collisions to the number of milliseconds specified in the subscription + int nowTime = PhysicsScene.SimulationNowTime; + if (nowTime >= NextCollisionOkTime) + { + NextCollisionOkTime = nowTime + SubscribedEventsMs; + + // We are called if we previously had collisions. If there are no collisions + // this time, send up one last empty event so OpenSim can sense collision end. + if (CollisionCollection.Count == 0) + PhysicsScene.ObjectsWithNoMoreCollisions.Add(this); + + base.SendCollisionUpdate(CollisionCollection); + + // The collisionCollection structure is passed around in the simulator. + // Make sure we don't have a handle to that one and that a new one is used next time. + CollisionCollection = new CollisionEventUpdate(); + } + } + + // Subscribe for collision events. + // Parameter is the millisecond rate the caller wishes collision events to occur. + public override void SubscribeEvents(int ms) { + SubscribedEventsMs = ms; + if (ms > 0) + { + // make sure first collision happens + NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); + PhysicsScene.PhysicsLogging.Write("{0},SubscribeEvents,call,ms={1},nextOKTime={2}", + LocalID, SubscribedEventsMs, NextCollisionOkTime.ToString("yyyyMMddHHmmssfff")); + + PhysicsScene.TaintedObject("BSPhysObject.SubscribeEvents", delegate() + { + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + }); + } + else + { + // Subscribing for zero or less is the same as unsubscribing + UnSubscribeEvents(); + } + } + public override void UnSubscribeEvents() { + SubscribedEventsMs = 0; + PhysicsScene.PhysicsLogging.Write("{0},UnSubscribeEvents,call", LocalID); + PhysicsScene.TaintedObject("BSPhysObject.UnSubscribeEvents", delegate() + { + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + }); + } + // Return 'true' if the simulator wants collision events + public override bool SubscribedEvents() { + return (SubscribedEventsMs > 0); + } + + #endregion // Collisions } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 26a581fc77..29f27e8192 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -49,8 +49,6 @@ public sealed class BSPrim : BSPhysObject private ulong _hullKey; private List _hulls; - private BSScene _scene; - public BSScene Scene { get { return _scene; } } private String _avName; private uint _localID = 0; @@ -87,18 +85,6 @@ public sealed class BSPrim : BSPhysObject private bool _kinematic; private float _buoyancy; - // Membership in a linkset is controlled by this class. - public override BSLinkset Linkset { get; set; } - - private int _subscribedEventsMs = 0; - private int _nextCollisionOkTime = 0; - long _collidingStep; - long _collidingGroundStep; - CollisionFlags m_currentCollisionFlags = 0; - - public override BulletBody BSBody { get; set; } - public override BulletShape BSShape { get; set; } - private BSDynamics _vehicle; private OMV.Vector3 _PIDTarget; @@ -113,10 +99,10 @@ public sealed class BSPrim : BSPhysObject OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) { // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); + base.BaseInitialize(parent_scene); _localID = localID; _avName = primName; _physicsActorType = (int)ActorTypes.Prim; - _scene = parent_scene; _position = pos; _size = size; _scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type @@ -129,25 +115,23 @@ public sealed class BSPrim : BSPhysObject _pbs = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; - _subscribedEventsMs = 0; - _friction = _scene.Params.defaultFriction; // TODO: compute based on object material - _density = _scene.Params.defaultDensity; // TODO: compute based on object material - _restitution = _scene.Params.defaultRestitution; - Linkset = new BSLinkset(Scene, this); // a linkset of one - _vehicle = new BSDynamics(Scene, this); // add vehicleness + _friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material + _density = PhysicsScene.Params.defaultDensity; // TODO: compute based on object material + _restitution = PhysicsScene.Params.defaultRestitution; + _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness _mass = CalculateMass(); DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time - _scene.TaintedObject("BSPrim.create", delegate() + PhysicsScene.TaintedObject("BSPrim.create", delegate() { CreateGeomAndObject(true); // Get the pointer to the physical body for this object. // At the moment, we're still letting BulletSim manage the creation and destruction // of the object. Someday we'll move that into the C# code. - BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); + BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID)); BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr)); - m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); + CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); }); } @@ -168,11 +152,11 @@ public sealed class BSPrim : BSPhysObject // Undo any vehicle properties this.VehicleType = (int)Vehicle.TYPE_NONE; - _scene.TaintedObject("BSPrim.destroy", delegate() + PhysicsScene.TaintedObject("BSPrim.destroy", delegate() { DetailLog("{0},BSPrim.Destroy,taint,", LocalID); // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. - BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); + BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID); }); } @@ -183,7 +167,7 @@ public sealed class BSPrim : BSPhysObject get { return _size; } set { _size = value; - _scene.TaintedObject("BSPrim.setSize", delegate() + PhysicsScene.TaintedObject("BSPrim.setSize", delegate() { _mass = CalculateMass(); // changing size changes the mass // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct @@ -196,7 +180,7 @@ public sealed class BSPrim : BSPhysObject public override PrimitiveBaseShape Shape { set { _pbs = value; - _scene.TaintedObject("BSPrim.setShape", delegate() + PhysicsScene.TaintedObject("BSPrim.setShape", delegate() { _mass = CalculateMass(); // changing the shape changes the mass CreateGeomAndObject(false); @@ -214,7 +198,7 @@ public sealed class BSPrim : BSPhysObject public override bool Selected { set { _isSelected = value; - _scene.TaintedObject("BSPrim.setSelected", delegate() + PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() { SetObjectDynamic(); }); @@ -283,13 +267,13 @@ public sealed class BSPrim : BSPhysObject _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); + // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); return _position; } set { _position = value; // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? - _scene.TaintedObject("BSPrim.setPosition", delegate() + PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); @@ -327,7 +311,7 @@ public sealed class BSPrim : BSPhysObject get { return _force; } set { _force = value; - _scene.TaintedObject("BSPrim.setForce", delegate() + PhysicsScene.TaintedObject("BSPrim.setForce", delegate() { DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); @@ -342,40 +326,40 @@ public sealed class BSPrim : BSPhysObject set { Vehicle type = (Vehicle)value; BSPrim vehiclePrim = this; - _scene.TaintedObject("setVehicleType", delegate() + PhysicsScene.TaintedObject("setVehicleType", delegate() { // Done at taint time so we're sure the physics engine is not using the variables // Vehicle code changes the parameters for this vehicle type. _vehicle.ProcessTypeChange(type); // Tell the scene about the vehicle so it will get processing each frame. - _scene.VehicleInSceneTypeChanged(this, type); + PhysicsScene.VehicleInSceneTypeChanged(this, type); }); } } public override void VehicleFloatParam(int param, float value) { - _scene.TaintedObject("BSPrim.VehicleFloatParam", delegate() + PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() { _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); }); } public override void VehicleVectorParam(int param, OMV.Vector3 value) { - _scene.TaintedObject("BSPrim.VehicleVectorParam", delegate() + PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() { _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); }); } public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { - _scene.TaintedObject("BSPrim.VehicleRotationParam", delegate() + PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() { _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); }); } public override void VehicleFlags(int param, bool remove) { - _scene.TaintedObject("BSPrim.VehicleFlags", delegate() + PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() { _vehicle.ProcessVehicleFlags(param, remove); }); @@ -393,8 +377,9 @@ public sealed class BSPrim : BSPhysObject public override void SetVolumeDetect(int param) { bool newValue = (param != 0); _isVolumeDetect = newValue; - _scene.TaintedObject("BSPrim.SetVolumeDetect", delegate() + PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() { + DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); SetObjectDynamic(); }); return; @@ -404,7 +389,7 @@ public sealed class BSPrim : BSPhysObject get { return _velocity; } set { _velocity = value; - _scene.TaintedObject("BSPrim.setVelocity", delegate() + PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() { DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity); @@ -438,9 +423,9 @@ public sealed class BSPrim : BSPhysObject set { _orientation = value; // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? - _scene.TaintedObject("BSPrim.setOrientation", delegate() + PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { - // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); }); @@ -454,8 +439,9 @@ public sealed class BSPrim : BSPhysObject get { return _isPhysical; } set { _isPhysical = value; - _scene.TaintedObject("BSPrim.setIsPhysical", delegate() + PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() { + DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); SetObjectDynamic(); }); } @@ -493,9 +479,9 @@ public sealed class BSPrim : BSPhysObject // Bullet wants static objects to have a mass of zero float mass = IsStatic ? 0f : _mass; - BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); + BulletSimAPI.SetObjectProperties(Scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); */ - BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr); + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); // Set up the object physicalness (does gravity and collisions move this object) MakeDynamic(IsStatic); @@ -506,15 +492,15 @@ public sealed class BSPrim : BSPhysObject // Arrange for collisions events if the simulator wants them EnableCollisions(SubscribedEvents()); - BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr); + BulletSimAPI.AddObjectToWorld2(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}, cf={4}", - LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3},collide={4},cf={5}", + LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags); } // "Making dynamic" means changing to and from static. @@ -527,7 +513,7 @@ public sealed class BSPrim : BSPhysObject if (makeStatic) { // Become a Bullet 'static' object type - m_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); // Center of mass is at the center of the object @@ -539,16 +525,17 @@ public sealed class BSPrim : BSPhysObject // 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 - m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); - // Set various physical properties so internal things will get computed correctly as they are set - BulletSimAPI.SetFriction2(BSBody.Ptr, Scene.Params.defaultFriction); - BulletSimAPI.SetRestitution2(BSBody.Ptr, Scene.Params.defaultRestitution); + // 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); // 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); @@ -562,10 +549,10 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); // Various values for simulation limits - BulletSimAPI.SetDamping2(BSBody.Ptr, Scene.Params.linearDamping, Scene.Params.angularDamping); - BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, Scene.Params.deactivationTime); - BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, Scene.Params.linearSleepingThreshold, Scene.Params.angularSleepingThreshold); - BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, Scene.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); @@ -581,11 +568,11 @@ public sealed class BSPrim : BSPhysObject if (makeSolid) { // Easy in Bullet -- just remove the object flag that controls collision response - m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); } else { - m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); } } @@ -594,11 +581,11 @@ public sealed class BSPrim : BSPhysObject { if (wantsCollisionEvents) { - m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } else { - m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } } @@ -618,11 +605,11 @@ public sealed class BSPrim : BSPhysObject set { _throttleUpdates = value; } } public override bool IsColliding { - get { return (_collidingStep == _scene.SimulationStep); } + get { return (CollidingStep == PhysicsScene.SimulationStep); } set { _isColliding = value; } } public override bool CollidingGround { - get { return (_collidingGroundStep == _scene.SimulationStep); } + get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } set { _collidingGround = value; } } public override bool CollidingObj { @@ -656,7 +643,7 @@ public sealed class BSPrim : BSPhysObject set { _rotationalVelocity = value; // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); - _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() + PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity); @@ -673,13 +660,13 @@ public sealed class BSPrim : BSPhysObject get { return _buoyancy; } set { _buoyancy = value; - _scene.TaintedObject("BSPrim.setBuoyancy", delegate() + PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() { DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object - float grav = Scene.Params.gravity * (1f - _buoyancy); + float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav)); - // BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); + // BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, _localID, _buoyancy); }); } } @@ -730,7 +717,7 @@ public sealed class BSPrim : BSPhysObject m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); return; } - _scene.TaintedObject("BSPrim.AddForce", delegate() + PhysicsScene.TaintedObject("BSPrim.AddForce", delegate() { OMV.Vector3 fSum = OMV.Vector3.Zero; lock (m_accumulatedForces) @@ -754,30 +741,6 @@ public sealed class BSPrim : BSPhysObject public override void SetMomentum(OMV.Vector3 momentum) { DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); } - public override void SubscribeEvents(int ms) { - _subscribedEventsMs = ms; - if (ms > 0) - { - // make sure first collision happens - _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; - - Scene.TaintedObject("BSPrim.SubscribeEvents", delegate() - { - m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - }); - } - } - public override void UnSubscribeEvents() { - _subscribedEventsMs = 0; - Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate() - { - m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - }); - } - public override bool SubscribedEvents() { - return (_subscribedEventsMs > 0); - } - #region Mass Calculation private float CalculateMass() @@ -1071,8 +1034,8 @@ public sealed class BSPrim : BSPhysObject if (returnMass <= 0) returnMass = 0.0001f; - if (returnMass > _scene.MaximumObjectMass) - returnMass = _scene.MaximumObjectMass; + if (returnMass > PhysicsScene.MaximumObjectMass) + returnMass = PhysicsScene.MaximumObjectMass; return returnMass; }// end CalculateMass @@ -1090,7 +1053,7 @@ public sealed class BSPrim : BSPhysObject bool haveShape = false; // If the prim attributes are simple, this could be a simple Bullet native shape - if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim) + if ((_pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) || (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0 && _pbs.ProfileHollow == 0 && _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0 @@ -1156,12 +1119,12 @@ public sealed class BSPrim : BSPhysObject private bool CreateGeomMesh() { // level of detail based on size and type of the object - float lod = _scene.MeshLOD; + float lod = PhysicsScene.MeshLOD; if (_pbs.SculptEntry) - lod = _scene.SculptLOD; + lod = PhysicsScene.SculptLOD; float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z)); - if (maxAxis > _scene.MeshMegaPrimThreshold) - lod = _scene.MeshMegaPrimLOD; + if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) + lod = PhysicsScene.MeshMegaPrimLOD; ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); @@ -1175,14 +1138,14 @@ public sealed class BSPrim : BSPhysObject { // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); - BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); + BulletSimAPI.DestroyMesh(PhysicsScene.WorldID, _meshKey); _mesh = null; _meshKey = 0; } _meshKey = newMeshKey; // always pass false for physicalness as this creates some sort of bounding box which we don't need - _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, lod, false); + _mesh = PhysicsScene.mesher.CreateMesh(_avName, _pbs, _size, lod, false); int[] indices = _mesh.getIndexListAsInt(); List vertices = _mesh.getVertexList(); @@ -1198,7 +1161,7 @@ public sealed class BSPrim : BSPhysObject // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", // LogHeader, _localID, _meshKey, indices.Length, vertices.Count); - BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, + BulletSimAPI.CreateMesh(PhysicsScene.WorldID, _meshKey, indices.GetLength(0), indices, vertices.Count, verticesAsFloats); _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; @@ -1211,7 +1174,7 @@ public sealed class BSPrim : BSPhysObject // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). private bool CreateGeomHull() { - float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; + float lod = _pbs.SculptEntry ? PhysicsScene.SculptLOD : PhysicsScene.MeshLOD; ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod); // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey); @@ -1225,7 +1188,7 @@ public sealed class BSPrim : BSPhysObject { // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); - BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); + BulletSimAPI.DestroyHull(PhysicsScene.WorldID, _hullKey); _hullKey = 0; } @@ -1314,7 +1277,7 @@ public sealed class BSPrim : BSPhysObject // create the hull definition in Bullet // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); - BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); + BulletSimAPI.CreateHull(PhysicsScene.WorldID, _hullKey, hullCount, convHulls); _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); @@ -1354,10 +1317,10 @@ public sealed class BSPrim : BSPhysObject ShapeData shape; FillShapeInfo(out shape); // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); - bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); + bool ret = BulletSimAPI.CreateObject(PhysicsScene.WorldID, shape); // the CreateObject() may have recreated the rigid body. Make sure we have the latest address. - BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); + BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID)); BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr)); return ret; @@ -1490,61 +1453,10 @@ public sealed class BSPrim : BSPhysObject } */ } - - // I've collided with something - // Called at taint time from within the Step() function - CollisionEventUpdate collisionCollection; - public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) - { - bool ret = false; - - // The following lines make IsColliding() and IsCollidingGround() work - _collidingStep = Scene.SimulationStep; - if (collidingWith <= Scene.TerrainManager.HighestTerrainID) - { - _collidingGroundStep = Scene.SimulationStep; - } - - // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); - - // prims in the same linkset cannot collide with each other - if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) - { - return ret; - } - - // if someone has subscribed for collision events.... - if (SubscribedEvents()) { - // throttle the collisions to the number of milliseconds specified in the subscription - int nowTime = Scene.SimulationNowTime; - if (nowTime >= _nextCollisionOkTime) { - _nextCollisionOkTime = nowTime + _subscribedEventsMs; - - if (collisionCollection == null) - collisionCollection = new CollisionEventUpdate(); - collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); - ret = true; - } - } - return ret; - } - - // The scene is telling us it's time to pass our collected collisions into the simulator - public override void SendCollisions() - { - if (collisionCollection != null && collisionCollection.Count > 0) - { - base.SendCollisionUpdate(collisionCollection); - // The collisionCollection structure is passed around in the simulator. - // Make sure we don't have a handle to that one and that a new one is used next time. - collisionCollection = null; - } - } - // Invoke the detailed logger and output something if it's enabled. private void DetailLog(string msg, params Object[] args) { - Scene.PhysicsLogging.Write(msg, args); + PhysicsScene.PhysicsLogging.Write(msg, args); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 52997dd526..dabced578e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -75,10 +75,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters public Dictionary PhysObjects = new Dictionary(); - private HashSet m_objectsWithCollisions = new HashSet(); - // Following is a kludge and can be removed when avatar animation updating is - // moved to a better place. - private HashSet m_avatarsWithCollisions = new HashSet(); + public HashSet ObjectsWithCollisions = new HashSet(); + public HashSet ObjectsWithNoMoreCollisions = new HashSet(); + // Keep track of all the avatars so we can send them a collision event + // every tick so OpenSim will update its animation. + private HashSet m_avatars = new HashSet(); // List of all the objects that have vehicle properties and should be called // to update each physics step. @@ -379,7 +380,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // TODO: Remove kludge someday. // We must generate a collision for avatars whether they collide or not. // This is required by OpenSim to update avatar animations, etc. - lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor); + lock (m_avatars) m_avatars.Add(actor); return actor; } @@ -397,7 +398,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters { lock (PhysObjects) PhysObjects.Remove(actor.LocalID); // Remove kludge someday - lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor); + lock (m_avatars) m_avatars.Remove(bsactor); } catch (Exception e) { @@ -464,6 +465,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters int collidersCount = 0; IntPtr collidersPtr; + int beforeTime = 0; + int simTime = 0; + // prevent simulation until we've been initialized if (!m_initialized) return 5.0f; @@ -481,10 +485,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters int numSubSteps = 0; try { + if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); + numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); - DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}", - DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); + + if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); + DetailLog("{0},Simulate,call, nTaints={1}, simTime={2}, substeps={3}, updates={4}, colliders={5}", + DetailLogZero, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); } catch (Exception e) { @@ -502,12 +510,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters // Get a value for 'now' so all the collision and update routines don't have to get their own SimulationNowTime = Util.EnvironmentTickCount(); - // This is a kludge to get avatar movement updates. - // ODE sends collisions for avatars even if there are have been no collisions. This updates - // avatar animations and stuff. - // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. - m_objectsWithCollisions = new HashSet(m_avatarsWithCollisions); - // If there were collisions, process them by sending the event to the prim. // Collisions must be processed before updates. if (collidersCount > 0) @@ -523,11 +525,31 @@ public class BSScene : PhysicsScene, IPhysicsParameters } } + // This is a kludge to get avatar movement updates. + // ODE sends collisions for avatars even if there are have been no collisions. This updates + // avatar animations and stuff. + // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. + foreach (BSPhysObject bsp in m_avatars) + bsp.SendCollisions(); + // The above SendCollision's batch up the collisions on the objects. // Now push the collisions into the simulator. - foreach (BSPhysObject bsp in m_objectsWithCollisions) - bsp.SendCollisions(); - m_objectsWithCollisions.Clear(); + // If the object is done colliding, it will add itself to the ObjectsWithNoMoreCollisions list. + if (ObjectsWithCollisions.Count > 0) + { + foreach (BSPhysObject bsp in ObjectsWithCollisions) + if (!m_avatars.Contains(bsp)) // don't call avatars twice + bsp.SendCollisions(); + } + + // Objects that are done colliding are removed from the ObjectsWithCollisions list. + // This can't be done by SendCollisions because it is inside an iteration of ObjectWithCollisions. + if (ObjectsWithNoMoreCollisions.Count > 0) + { + foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) + ObjectsWithCollisions.Remove(po); + ObjectsWithNoMoreCollisions.Clear(); + } // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) @@ -555,7 +577,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // The physics engine returns the number of milliseconds it simulated this call. // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. // Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS. - return numSubSteps * m_fixedTimeStep; + return numSubSteps * m_fixedTimeStep * 1000; } // Something has collided @@ -583,7 +605,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) { // If a collision was posted, remember to send it to the simulator - m_objectsWithCollisions.Add(collider); + ObjectsWithCollisions.Add(collider); } return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 9221cdb30e..4d2d9623a7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -249,7 +249,16 @@ public enum CollisionFlags : uint BS_PHYSICAL_OBJECT = 1 << 13, BS_TERRAIN_OBJECT = 1 << 14, BS_NONE = 0, - BS_ALL = 0xFFFFFFFF + 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_VOLUME_DETECT_OBJECT + | BS_PHANTOM_OBJECT + | BS_PHYSICAL_OBJECT, }; // Values for collisions groups and masks @@ -270,52 +279,6 @@ public enum CollisionFilterGroups : uint SolidFilter = 1 << 13, }; - // For each type, we first clear and then set the collision flags -public enum ClearCollisionFlag : uint -{ - Terrain = CollisionFlags.BS_ALL, - Phantom = CollisionFlags.BS_ALL, - VolumeDetect = CollisionFlags.BS_ALL, - PhysicalObject = CollisionFlags.BS_ALL, - StaticObject = CollisionFlags.BS_ALL -} - -public enum SetCollisionFlag : uint -{ - Terrain = CollisionFlags.CF_STATIC_OBJECT - | CollisionFlags.BS_TERRAIN_OBJECT, - Phantom = CollisionFlags.CF_STATIC_OBJECT - | CollisionFlags.BS_PHANTOM_OBJECT - | CollisionFlags.CF_NO_CONTACT_RESPONSE, - VolumeDetect = CollisionFlags.CF_STATIC_OBJECT - | CollisionFlags.BS_VOLUME_DETECT_OBJECT - | CollisionFlags.CF_NO_CONTACT_RESPONSE, - PhysicalObject = CollisionFlags.BS_PHYSICAL_OBJECT, - StaticObject = CollisionFlags.CF_STATIC_OBJECT, -} - -// Collision filters used for different types of objects -public enum SetCollisionFilter : uint -{ - Terrain = CollisionFilterGroups.AllFilter, - Phantom = CollisionFilterGroups.GroundPlaneFilter - | CollisionFilterGroups.TerrainFilter, - VolumeDetect = CollisionFilterGroups.AllFilter, - PhysicalObject = CollisionFilterGroups.AllFilter, - StaticObject = CollisionFilterGroups.AllFilter, -} - -// Collision masks used for different types of objects -public enum SetCollisionMask : uint -{ - Terrain = CollisionFilterGroups.AllFilter, - Phantom = CollisionFilterGroups.GroundPlaneFilter - | CollisionFilterGroups.TerrainFilter, - VolumeDetect = CollisionFilterGroups.AllFilter, - PhysicalObject = CollisionFilterGroups.AllFilter, - StaticObject = CollisionFilterGroups.AllFilter -} - // CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 // ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2. public enum ConstraintParams : int