From ee7cda261cbbc9dcd558c35eabc070cc0bf45644 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 18 Sep 2012 08:39:52 -0700 Subject: BulletSim: move a bunch of common logic out of BSPrim and BSCharacter and into the parent class BSPhysObject. Rework collision logic to enable extra collision after done colliding. Rename 'Scene' to 'PhysicsScene' to differentiate it from the simulator 'Scene'. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 238 +++++++-------------- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 10 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 42 ++-- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 138 +++++++++++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 232 +++++++------------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 60 ++++-- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 57 +---- 7 files changed, 361 insertions(+), 416 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 526dbad..57d5726 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 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 AddAngularForce(OMV.Vector3 force, bool pushforce) { } - - 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 61006f0..2da2331 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 7e784eb..005a758 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 3fe71e1..242aa80 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 26a581f..29f27e8 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 52997dd..dabced5 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 9221cdb..4d2d962 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 -- cgit v1.1