From 783443705da92c2ebc85c7999d11ef79d014dd73 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 3 Nov 2012 12:03:47 -0700 Subject: HG Suitcase Inventory: if RootFolder type doesn't work, look for any folder with parentID=UUID.Zero --- OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index 677bd7b..784f136 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -460,6 +460,15 @@ namespace OpenSim.Services.HypergridService if (folders != null && folders.Length > 0) return folders[0]; + + // OK, so the RootFolder type didn't work. Let's look for any type with parent UUID.Zero. + folders = m_Database.GetFolders( + new string[] { "agentID", "folderName", "parentFolderID" }, + new string[] { principalID.ToString(), "My Inventory", UUID.Zero.ToString() }); + + if (folders != null && folders.Length > 0) + return folders[0]; + return null; } -- cgit v1.1 From 804b332d45c3989958f5ec08e1509ba373fb84b1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 25 Oct 2012 08:04:20 -0700 Subject: BulletSim: Add banking and other new code to vechile dynamics. Add third party license and contributor in for for Aurora-Sim project for physics code. --- CONTRIBUTORS.txt | 2 + .../Physics/BulletSPlugin/BS6DofConstraint.cs | 2 +- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- .../BulletSPlugin/BSConstraintCollection.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 489 +++++++++++++-------- .../Physics/BulletSPlugin/BSHingeConstraint.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 2 + .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 2 +- ThirdPartyLicenses/Aurora-Sim.txt | 26 ++ 13 files changed, 351 insertions(+), 188 deletions(-) create mode 100644 ThirdPartyLicenses/Aurora-Sim.txt diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index fd00fe8..e5a6d49 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -182,12 +182,14 @@ what it is today. This software uses components from the following developers: * Sleepycat Software (Berkeley DB) +* Aurora-Sim (http://aurora-sim.org) * SQLite (Public Domain) * XmlRpcCS (http://xmlrpccs.sf.net/) * MySQL, Inc. (MySQL Connector/NET) * NUnit (http://www.nunit.org) * AGEIA Inc. (PhysX) * Russel L. Smith (ODE) +* Erwin Coumans (Bullet) * Prebuild (http://sourceforge.net/projects/dnpb/) * LibOpenMetaverse (http://lib.openmetaverse.org/) * DotNetOpenMail v0.5.8b (http://dotnetopenmail.sourceforge.net) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs index 3306a97..310df3d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs @@ -32,7 +32,7 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BS6DofConstraint : BSConstraint +public sealed class BS6DofConstraint : BSConstraint { private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index a041ba8..9fea9b8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -34,7 +34,7 @@ using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSCharacter : BSPhysObject +public sealed class BSCharacter : BSPhysObject { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS CHAR]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs index 22ea367..b9add06 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -33,7 +33,7 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSConstraintCollection : IDisposable +public sealed class BSConstraintCollection : IDisposable { // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // private static readonly string LogHeader = "[CONSTRAINT COLLECTION]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 117c878..9b59bef 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -52,7 +52,7 @@ using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Physics.BulletSPlugin { - public class BSDynamics + public sealed class BSDynamics { private BSScene PhysicsScene { get; set; } // the prim this dynamic controller belongs to @@ -72,8 +72,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // LIMIT_ROLL_ONLY private Vector3 m_BlockingEndPoint = Vector3.Zero; private Quaternion m_RollreferenceFrame = Quaternion.Identity; + private Quaternion m_referenceFrame = Quaternion.Identity; + // Linear properties private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time + private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body private Vector3 m_linearFrictionTimescale = Vector3.Zero; @@ -95,19 +98,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body //Deflection properties - // private float m_angularDeflectionEfficiency = 0; - // private float m_angularDeflectionTimescale = 0; - // private float m_linearDeflectionEfficiency = 0; - // private float m_linearDeflectionTimescale = 0; + private float m_angularDeflectionEfficiency = 0; + private float m_angularDeflectionTimescale = 0; + private float m_linearDeflectionEfficiency = 0; + private float m_linearDeflectionTimescale = 0; //Banking properties - // private float m_bankingEfficiency = 0; - // private float m_bankingMix = 0; - // private float m_bankingTimescale = 0; + private float m_bankingEfficiency = 0; + private float m_bankingMix = 0; + private float m_bankingTimescale = 0; //Hover and Buoyancy properties private float m_VhoverHeight = 0f; -// private float m_VhoverEfficiency = 0f; + private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. @@ -138,10 +141,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin switch (pParam) { case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: - // m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); + m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); break; case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: - // m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); + m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f); @@ -150,20 +153,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularMotorTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.BANKING_EFFICIENCY: - // m_bankingEfficiency = Math.Max(pValue, 0.01f); + m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); break; case Vehicle.BANKING_MIX: - // m_bankingMix = Math.Max(pValue, 0.01f); + m_bankingMix = Math.Max(pValue, 0.01f); break; case Vehicle.BANKING_TIMESCALE: - // m_bankingTimescale = Math.Max(pValue, 0.01f); + m_bankingTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.BUOYANCY: m_VehicleBuoyancy = Math.Max(-1f, Math.Min(pValue, 1f)); break; -// case Vehicle.HOVER_EFFICIENCY: -// m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f)); -// break; + case Vehicle.HOVER_EFFICIENCY: + m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f)); + break; case Vehicle.HOVER_HEIGHT: m_VhoverHeight = pValue; break; @@ -171,10 +174,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_VhoverTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: - // m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); + m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); break; case Vehicle.LINEAR_DEFLECTION_TIMESCALE: - // m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); + m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f); @@ -196,7 +199,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.ANGULAR_MOTOR_DIRECTION: m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - m_angularMotorApply = 10; + m_angularMotorApply = 100; break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); @@ -206,7 +209,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); break; case Vehicle.LINEAR_MOTOR_OFFSET: - // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); + m_linearMotorOffset = new Vector3(pValue, pValue, pValue); break; } @@ -221,15 +224,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.ANGULAR_MOTOR_DIRECTION: - m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // Limit requested angular speed to 2 rps= 4 pi rads/sec - if (m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; - if (m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; - if (m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; - if (m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; - if (m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; - if (m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; - m_angularMotorApply = 10; + pValue.X = Math.Max(-12.56f, Math.Min(pValue.X, 12.56f)); + pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); + pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); + m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_angularMotorApply = 100; break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -239,7 +239,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.LINEAR_MOTOR_OFFSET: - // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.BLOCK_EXIT: m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -253,7 +253,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin switch (pParam) { case Vehicle.REFERENCE_FRAME: - // m_referenceFrame = pValue; + m_referenceFrame = pValue; break; case Vehicle.ROLL_FRAME: m_RollreferenceFrame = pValue; @@ -265,21 +265,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin { VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); VehicleFlag parm = (VehicleFlag)pParam; - if (remove) + if (pParam == -1) + m_flags = (VehicleFlag)0; + else { - if (pParam == -1) - { - m_flags = (VehicleFlag)0; - } - else - { + if (remove) m_flags &= ~parm; - } - } - else { - m_flags |= parm; + else + m_flags |= parm; } - }//end ProcessVehicleFlags + } internal void ProcessTypeChange(Vehicle pType) { @@ -288,99 +283,142 @@ namespace OpenSim.Region.Physics.BulletSPlugin Type = pType; switch (pType) { - case Vehicle.TYPE_NONE: - m_linearFrictionTimescale = new Vector3(0, 0, 0); - m_angularFrictionTimescale = new Vector3(0, 0, 0); + case Vehicle.TYPE_NONE: m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 0; m_linearMotorDecayTimescale = 0; + m_linearFrictionTimescale = new Vector3(0, 0, 0); + m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 0; m_angularMotorDecayTimescale = 0; + m_angularMotorTimescale = 0; + m_angularFrictionTimescale = new Vector3(0, 0, 0); + m_VhoverHeight = 0; + m_VhoverEfficiency = 0; m_VhoverTimescale = 0; m_VehicleBuoyancy = 0; + + m_linearDeflectionEfficiency = 1; + m_linearDeflectionTimescale = 1; + + m_angularDeflectionEfficiency = 0; + m_angularDeflectionTimescale = 1000; + + m_verticalAttractionEfficiency = 0; + m_verticalAttractionTimescale = 0; + + m_bankingEfficiency = 0; + m_bankingTimescale = 1000; + m_bankingMix = 1; + + m_referenceFrame = Quaternion.Identity; m_flags = (VehicleFlag)0; break; case Vehicle.TYPE_SLED: - m_linearFrictionTimescale = new Vector3(30, 1, 1000); - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 1000; m_linearMotorDecayTimescale = 120; + m_linearFrictionTimescale = new Vector3(30, 1, 1000); + m_angularMotorDirection = Vector3.Zero; m_angularMotorTimescale = 1000; m_angularMotorDecayTimescale = 120; + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_VhoverHeight = 0; -// m_VhoverEfficiency = 1; + m_VhoverEfficiency = 10; // TODO: this looks wrong!! m_VhoverTimescale = 10; m_VehicleBuoyancy = 0; - // m_linearDeflectionEfficiency = 1; - // m_linearDeflectionTimescale = 1; - // m_angularDeflectionEfficiency = 1; - // m_angularDeflectionTimescale = 1000; - // m_bankingEfficiency = 0; - // m_bankingMix = 1; - // m_bankingTimescale = 10; - // m_referenceFrame = Quaternion.Identity; + + m_linearDeflectionEfficiency = 1; + m_linearDeflectionTimescale = 1; + + m_angularDeflectionEfficiency = 1; + m_angularDeflectionTimescale = 1000; + + m_verticalAttractionEfficiency = 0; + m_verticalAttractionTimescale = 0; + + m_bankingEfficiency = 0; + m_bankingTimescale = 10; + m_bankingMix = 1; + + m_referenceFrame = Quaternion.Identity; m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); break; case Vehicle.TYPE_CAR: - m_linearFrictionTimescale = new Vector3(100, 2, 1000); - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 1; m_linearMotorDecayTimescale = 60; + m_linearFrictionTimescale = new Vector3(100, 2, 1000); + m_angularMotorDirection = Vector3.Zero; m_angularMotorTimescale = 1; m_angularMotorDecayTimescale = 0.8f; + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_VhoverHeight = 0; -// m_VhoverEfficiency = 0; + m_VhoverEfficiency = 0; m_VhoverTimescale = 1000; m_VehicleBuoyancy = 0; - // // m_linearDeflectionEfficiency = 1; - // // m_linearDeflectionTimescale = 2; - // // m_angularDeflectionEfficiency = 0; - // m_angularDeflectionTimescale = 10; + + m_linearDeflectionEfficiency = 1; + m_linearDeflectionTimescale = 2; + + m_angularDeflectionEfficiency = 0; + m_angularDeflectionTimescale = 10; + m_verticalAttractionEfficiency = 1f; m_verticalAttractionTimescale = 10f; - // m_bankingEfficiency = -0.2f; - // m_bankingMix = 1; - // m_bankingTimescale = 1; - // m_referenceFrame = Quaternion.Identity; + + m_bankingEfficiency = -0.2f; + m_bankingMix = 1; + m_bankingTimescale = 1; + + m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT); m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.LIMIT_MOTOR_UP); - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); - m_flags |= (VehicleFlag.HOVER_UP_ONLY); + | VehicleFlag.LIMIT_MOTOR_UP + | VehicleFlag.HOVER_UP_ONLY); break; case Vehicle.TYPE_BOAT: - m_linearFrictionTimescale = new Vector3(10, 3, 2); - m_angularFrictionTimescale = new Vector3(10,10,10); m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 5; m_linearMotorDecayTimescale = 60; + m_linearFrictionTimescale = new Vector3(10, 3, 2); + m_angularMotorDirection = Vector3.Zero; m_angularMotorTimescale = 4; m_angularMotorDecayTimescale = 4; + m_angularFrictionTimescale = new Vector3(10,10,10); + m_VhoverHeight = 0; -// m_VhoverEfficiency = 0.5f; + m_VhoverEfficiency = 0.5f; m_VhoverTimescale = 2; m_VehicleBuoyancy = 1; - // m_linearDeflectionEfficiency = 0.5f; - // m_linearDeflectionTimescale = 3; - // m_angularDeflectionEfficiency = 0.5f; - // m_angularDeflectionTimescale = 5; + + m_linearDeflectionEfficiency = 0.5f; + m_linearDeflectionTimescale = 3; + + m_angularDeflectionEfficiency = 0.5f; + m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 0.5f; m_verticalAttractionTimescale = 5f; - // m_bankingEfficiency = -0.3f; - // m_bankingMix = 0.8f; - // m_bankingTimescale = 1; - // m_referenceFrame = Quaternion.Identity; + + m_bankingEfficiency = -0.3f; + m_bankingMix = 0.8f; + m_bankingTimescale = 1; + + m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.LIMIT_ROLL_ONLY @@ -390,28 +428,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin | VehicleFlag.HOVER_WATER_ONLY); break; case Vehicle.TYPE_AIRPLANE: - m_linearFrictionTimescale = new Vector3(200, 10, 5); - m_angularFrictionTimescale = new Vector3(20, 20, 20); m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 2; m_linearMotorDecayTimescale = 60; + m_linearFrictionTimescale = new Vector3(200, 10, 5); + m_angularMotorDirection = Vector3.Zero; m_angularMotorTimescale = 4; m_angularMotorDecayTimescale = 4; + m_angularFrictionTimescale = new Vector3(20, 20, 20); + m_VhoverHeight = 0; -// m_VhoverEfficiency = 0.5f; + m_VhoverEfficiency = 0.5f; m_VhoverTimescale = 1000; m_VehicleBuoyancy = 0; - // m_linearDeflectionEfficiency = 0.5f; - // m_linearDeflectionTimescale = 3; - // m_angularDeflectionEfficiency = 1; - // m_angularDeflectionTimescale = 2; + + m_linearDeflectionEfficiency = 0.5f; + m_linearDeflectionTimescale = 3; + + m_angularDeflectionEfficiency = 1; + m_angularDeflectionTimescale = 2; + m_verticalAttractionEfficiency = 0.9f; m_verticalAttractionTimescale = 2f; - // m_bankingEfficiency = 1; - // m_bankingMix = 0.7f; - // m_bankingTimescale = 2; - // m_referenceFrame = Quaternion.Identity; + + m_bankingEfficiency = 1; + m_bankingMix = 0.7f; + m_bankingTimescale = 2; + + m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT @@ -421,28 +466,36 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); break; case Vehicle.TYPE_BALLOON: - m_linearFrictionTimescale = new Vector3(5, 5, 5); - m_angularFrictionTimescale = new Vector3(10, 10, 10); m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 5; + m_linearFrictionTimescale = new Vector3(5, 5, 5); m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; m_angularMotorTimescale = 6; + m_angularFrictionTimescale = new Vector3(10, 10, 10); m_angularMotorDecayTimescale = 10; + m_VhoverHeight = 5; -// m_VhoverEfficiency = 0.8f; + m_VhoverEfficiency = 0.8f; m_VhoverTimescale = 10; m_VehicleBuoyancy = 1; - // m_linearDeflectionEfficiency = 0; - // m_linearDeflectionTimescale = 5; - // m_angularDeflectionEfficiency = 0; - // m_angularDeflectionTimescale = 5; + + m_linearDeflectionEfficiency = 0; + m_linearDeflectionTimescale = 5; + + m_angularDeflectionEfficiency = 0; + m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 1f; m_verticalAttractionTimescale = 100f; - // m_bankingEfficiency = 0; - // m_bankingMix = 0.7f; - // m_bankingTimescale = 5; - // m_referenceFrame = Quaternion.Identity; + + m_bankingEfficiency = 0; + m_bankingMix = 0.7f; + m_bankingTimescale = 5; + m_referenceFrame = Quaternion.Identity; + + m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_UP_ONLY @@ -452,21 +505,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin | VehicleFlag.HOVER_GLOBAL_HEIGHT); break; } - }//end SetDefaultsForType + } // Some of the properties of this prim may have changed. // Do any updating needed for a vehicle public void Refresh() { - if (!IsActive) - return; - - // Set the prim's inertia to zero. The vehicle code handles that and this - // removes the motion and torque actions introduced by Bullet. - Vector3 inertia = Vector3.Zero; - // comment out for DEBUG test - // BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, inertia); - // BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr); + /* + * Doesnt work unless BSDynamics senses and corrects for all collisions + if (IsActive) + BulletSimAPI.AddToCollisionFlags2(Prim.BSBody.ptr, CollisionFlags.CF_KINEMATIC_OBJECT); + else + BulletSimAPI.RemoveFromCollisionFlags2(Prim.BSBody.ptr, CollisionFlags.CF_KINEMATIC_OBJECT); + */ + /* + * Doesn't work because with zero inertia, Bullet will not apply any forces to the object. + if (IsActive) + { + BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, Vector3.Zero); + BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr); + } + */ } // One step of the vehicle properties for the next 'pTimestep' seconds. @@ -478,6 +537,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin MoveAngular(pTimestep); LimitRotation(pTimestep); + /* Experimental + // Wonder if Bullet could handle collision penetration while this applies the forces. + // Apply the computed forces on the vehicle + Prim.ForcePosition += Prim.ForceVelocity * Prim.MassRaw * pTimestep; + + if (Prim.ForceRotationalVelocity != Vector3.Zero) + { + Quaternion newOrientation = Prim.ForceOrientation; + newOrientation.Normalize(); + Quaternion appliedRotation = new Quaternion((Prim.ForceRotationalVelocity * pTimestep), 0f); + newOrientation += (appliedRotation * newOrientation) * 0.5f; + newOrientation.Normalize(); + Prim.ForceOrientation = newOrientation; + } + */ + // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; @@ -489,59 +564,46 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Also does hover and float. private void MoveLinear(float pTimestep) { - // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates - // m_lastLinearVelocityVector is the speed we are moving in that direction + // m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates + // m_lastLinearVelocityVector is the current speed we are moving in that direction if (m_linearMotorDirection.LengthSquared() > 0.001f) { Vector3 origDir = m_linearMotorDirection; Vector3 origVel = m_lastLinearVelocityVector; // add drive to body - // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale / pTimestep); Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep); // lastLinearVelocityVector is the current body velocity vector - // RA: Not sure what the *10 is for. A correction for pTimestep? - // m_lastLinearVelocityVector += (addAmount*10); m_lastLinearVelocityVector += addAmount; - // Limit the velocity vector to less than the last set linear motor direction - if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) - m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; - if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) - m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; - if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) - m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; - - /* - // decay applied velocity - Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep); - // (RA: do not know where the 0.5f comes from) - m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; - */ float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep)); m_linearMotorDirection *= keepfraction; VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}", Prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector); + + // convert requested object velocity to object relative vector + m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; } else { // if what remains of direction is very small, zero it. m_linearMotorDirection = Vector3.Zero; m_lastLinearVelocityVector = Vector3.Zero; + m_newVelocity = Vector3.Zero; + VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); } - // convert requested object velocity to object relative vector - Quaternion rotq = Prim.ForceOrientation; - m_newVelocity = m_lastLinearVelocityVector * rotq; + // m_newVelocity is velocity computed from linear motor // Add the various forces into m_dir which will be our new direction vector (velocity) // 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 = Prim.PhysicsScene.DefaultGravity * (Prim.Linkset.LinksetMass * (1f - m_VehicleBuoyancy)); + // Vector3 grav = Prim.PhysicsScene.DefaultGravity * (Prim.Linkset.LinksetMass * (1f - m_VehicleBuoyancy)); + Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); /* * RA: Not sure why one would do this @@ -567,6 +629,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // Check if hovering + // m_VhoverEfficiency: 0=bouncy, 1=totally damped + // m_VhoverTimescale: time to achieve height if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) { // We should hover, get the target height @@ -597,13 +661,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - float herr0 = pos.Z - m_VhoverTargetHeight; + float horizontalError = pos.Z - m_VhoverTargetHeight; + // RA: where does the 50 come from> + float horizontalCorrectionVelocity = ((horizontalError * 50.0f) / (m_VhoverTimescale / pTimestep)); // Replace Vertical speed with correction figure if significant - if (Math.Abs(herr0) > 0.01f) + if (Math.Abs(horizontalError) > 0.01f) { - m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); + m_newVelocity.Z += horizontalCorrectionVelocity; //KF: m_VhoverEfficiency is not yet implemented } + else if (horizontalError < -0.01) + { + m_newVelocity.Z -= horizontalCorrectionVelocity; + } else { m_newVelocity.Z = 0f; @@ -678,16 +748,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_flags & (VehicleFlag.NO_Z)) != 0) m_newVelocity.Z = 0; - // Apply velocity - Prim.ForceVelocity = m_newVelocity; - // apply gravity force - // Why is this set here? The physics engine already does gravity. - Prim.AddForce(grav, false, true); - // Apply friction Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep)); m_lastLinearVelocityVector *= keepFraction; + // Apply velocity + // Prim.ForceVelocity = m_newVelocity; + Prim.AddForce(m_newVelocity, false); + VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}", Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction); @@ -717,11 +785,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 origDir = m_angularMotorDirection; // ramp up to new value - // new velocity += error / ( time to get there / step interval) - // requested speed - last motor speed - m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); - m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); - m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); + // new velocity += error / ( time to get there / step interval) + // requested speed - last motor speed + m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},origDir={5},vel={6}", Prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); @@ -732,46 +798,50 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // No motor recently applied, keep the body velocity // and decay the velocity - m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); - if (m_angularMotorVelocity.LengthSquared() < 0.00001) + if (m_angularMotorVelocity.LengthSquared() < 0.0001) m_angularMotorVelocity = Vector3.Zero; + else + m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); } // end motor section - // Vertical attractor section + #region Vertical attactor + Vector3 vertattr = Vector3.Zero; Vector3 deflection = Vector3.Zero; Vector3 banking = Vector3.Zero; if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) { - float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep); + float VAservo = 0.2f; + if (Prim.Linkset.LinksetIsColliding) + VAservo = 0.05f / (m_verticalAttractionTimescale / pTimestep); + VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); // get present body rotation Quaternion rotq = Prim.ForceOrientation; // vector pointing up - Vector3 verterr = Vector3.Zero; - verterr.Z = 1.0f; + Vector3 verticalError = Vector3.UnitZ; // rotate it to Body Angle - verterr = verterr * rotq; - // verterr.X and .Y are the World error amounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. + verticalError = verticalError * rotq; + // verticalError.X and .Y are the World error amounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. // Error is 0 (no error) to +/- 2 (max error) - if (verterr.Z < 0.0f) + if (verticalError.Z < 0.0f) { - verterr.X = 2.0f - verterr.X; - verterr.Y = 2.0f - verterr.Y; + verticalError.X = 2.0f - verticalError.X; + verticalError.Y = 2.0f - verticalError.Y; } // scale it by VAservo - verterr = verterr * VAservo; + verticalError = verticalError * VAservo; - // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so + // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y then .X increases, so // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. - vertattr.X = verterr.Y; - vertattr.Y = - verterr.X; + vertattr.X = verticalError.Y; + vertattr.Y = - verticalError.X; vertattr.Z = 0f; // scaling appears better usingsquare-law @@ -779,10 +849,77 @@ namespace OpenSim.Region.Physics.BulletSPlugin vertattr.X += bounce * angularVelocity.X; vertattr.Y += bounce * angularVelocity.Y; - VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", - Prim.LocalID, verterr, bounce, vertattr); + VDetailLog("{0},MoveAngular,verticalAttraction,verticalError={1},bounce={2},vertattr={3}", + Prim.LocalID, verticalError, bounce, vertattr); + + } + #endregion // Vertical attactor + + #region Deflection + + //Forward is the prefered direction, but if the reference frame has changed, we need to take this into account as well + Vector3 PreferredAxisOfMotion = + new Vector3((10*(m_angularDeflectionEfficiency/m_angularDeflectionTimescale)), 0, 0); + PreferredAxisOfMotion *= Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); + + //Multiply it so that it scales linearly + //deflection = PreferredAxisOfMotion; + + //deflection = ((PreferredAxisOfMotion * m_angularDeflectionEfficiency) / (m_angularDeflectionTimescale / pTimestep)); + + #endregion - } // else vertical attractor is off + #region Banking + + if (m_bankingEfficiency != 0) + { + Vector3 dir = Vector3.One * Prim.ForceOrientation; + float mult = (m_bankingMix*m_bankingMix)*-1*(m_bankingMix < 0 ? -1 : 1); + //Changes which way it banks in and out of turns + + //Use the square of the efficiency, as it looks much more how SL banking works + float effSquared = (m_bankingEfficiency*m_bankingEfficiency); + if (m_bankingEfficiency < 0) + effSquared *= -1; //Keep the negative! + + float mix = Math.Abs(m_bankingMix); + if (m_angularMotorVelocity.X == 0) + { + /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) + { + Vector3 axisAngle; + float angle; + parent.Orientation.GetAxisAngle(out axisAngle, out angle); + Vector3 rotatedVel = parent.Velocity * parent.Orientation; + if ((rotatedVel.X < 0 && axisAngle.Y > 0) || (rotatedVel.X > 0 && axisAngle.Y < 0)) + m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (1f) * 10; + else + m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (-1f) * 10; + }*/ + } + else + banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4; + if (!Prim.Linkset.LinksetIsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) + //If they are colliding, we probably shouldn't shove the prim around... probably + { + float angVelZ = m_angularMotorVelocity.X*-1; + /*if(angVelZ > mix) + angVelZ = mix; + else if(angVelZ < -mix) + angVelZ = -mix;*/ + //This controls how fast and how far the banking occurs + Vector3 bankingRot = new Vector3(angVelZ*(effSquared*mult), 0, 0); + if (bankingRot.X > 3) + bankingRot.X = 3; + else if (bankingRot.X < -3) + bankingRot.X = -3; + bankingRot *= Prim.ForceOrientation; + banking += bankingRot; + } + m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; + } + + #endregion m_lastVertAttractor = vertattr; @@ -811,7 +948,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; // Apply to the body - Prim.ForceRotationalVelocity = m_lastAngularVelocity; + // Prim.ForceRotationalVelocity = m_lastAngularVelocity; + Prim.AddAngularForce(m_lastAngularVelocity, false); VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity); } //end MoveAngular @@ -820,38 +958,31 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Quaternion rotq = Prim.ForceOrientation; Quaternion m_rot = rotq; - bool changed = false; if (m_RollreferenceFrame != Quaternion.Identity) { if (rotq.X >= m_RollreferenceFrame.X) { m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); - changed = true; } if (rotq.Y >= m_RollreferenceFrame.Y) { m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); - changed = true; } if (rotq.X <= -m_RollreferenceFrame.X) { m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); - changed = true; } if (rotq.Y <= -m_RollreferenceFrame.Y) { m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); - changed = true; } - changed = true; } if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) { m_rot.X = 0; m_rot.Y = 0; - changed = true; } - if (changed) + if (rotq != m_rot) { Prim.ForceOrientation = m_rot; VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs index 7c8a215..76bd930 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs @@ -32,7 +32,7 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -class BSHingeConstraint : BSConstraint +public sealed class BSHingeConstraint : BSConstraint { public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index c984824..24fe6b9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -88,6 +88,8 @@ public abstract class BSLinkset } } + public virtual bool LinksetIsColliding { get { return false; } } + public OMV.Vector3 CenterOfMass { get { return ComputeLinksetCenterOfMass(); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 8a750b5..003c294 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -32,7 +32,7 @@ using OMV = OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSLinksetConstraints : BSLinkset +public sealed class BSLinksetConstraints : BSLinkset { // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 38ab3de..39d20dc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -311,6 +311,7 @@ public sealed class BSPrim : BSPhysObject if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); + // TODO: a floating motor so object will bob in the water if (Position.Z < waterHeight) { _position.Z = waterHeight; @@ -902,7 +903,8 @@ public sealed class BSPrim : BSPhysObject } // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. - BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); + if (fSum != OMV.Vector3.Zero) + BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); }; if (inTaintTime) addForceOperation(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index db0c99e..9e95ce5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -62,7 +62,7 @@ using OpenMetaverse; // namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSScene : PhysicsScene, IPhysicsParameters +public sealed class BSScene : PhysicsScene, IPhysicsParameters { private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS SCENE]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 30fa50a..1c0e6f5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -34,7 +34,7 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSShapeCollection : IDisposable +public sealed class BSShapeCollection : IDisposable { private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 880859a..11298fe 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -40,7 +40,7 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSTerrainManager +public sealed class BSTerrainManager { static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; diff --git a/ThirdPartyLicenses/Aurora-Sim.txt b/ThirdPartyLicenses/Aurora-Sim.txt new file mode 100644 index 0000000..162d552 --- /dev/null +++ b/ThirdPartyLicenses/Aurora-Sim.txt @@ -0,0 +1,26 @@ +/* + * Copyright (c) Contributors, http://aurora-sim.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Aurora-Sim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ -- cgit v1.1 From b83449ae9ad3073abaa06167a99c47943c3199c2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Oct 2012 13:47:28 -0700 Subject: BulletSim: correct spelling of Bullet call. It's 'swept' not 'sweep'. --- OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs | 4 ++++ OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs index 310df3d..ecb3ec8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs @@ -135,7 +135,11 @@ public sealed class BS6DofConstraint : BSConstraint bool ret = false; float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; if (m_enabled) + { ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce); + m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}", + BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce); + } return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 9fea9b8..8bb4b21 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -152,7 +152,7 @@ public sealed class BSCharacter : BSPhysObject if (PhysicsScene.Params.ccdMotionThreshold > 0f) { BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 5ffd591..be3a5ad 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -881,10 +881,10 @@ public static extern float GetCcdMotionThreshold2(IntPtr obj); public static extern void SetCcdMotionThreshold2(IntPtr obj, float val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetCcdSweepSphereRadius2(IntPtr obj); +public static extern float GetCcdSweptSphereRadius2(IntPtr obj); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCcdSweepSphereRadius2(IntPtr obj, float val); +public static extern void SetCcdSweptSphereRadius2(IntPtr obj, float val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr GetUserPointer2(IntPtr obj); -- cgit v1.1 From 8fa83cf43045401ee02321e0fb1191402db5bb05 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Oct 2012 13:49:57 -0700 Subject: BulletSim: Add activations after vehicle properties change. Problem was the vehicle was going to sleep while waiting for commands. Make AddAngularForce work the same way as AddForce -- accumulates values and pushes them once into Bullet. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 74 +++++++++++++++++++++----- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 39d20dc..44937df 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -242,8 +242,8 @@ public sealed class BSPrim : BSPhysObject _acceleration = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; - // Zero some other properties directly into the physics engine - BulletSimAPI.ClearForces2(BSBody.ptr); + // Zero some other properties in the physics engine + BulletSimAPI.ClearAllForces2(BSBody.ptr); } public override void LockAngularMotion(OMV.Vector3 axis) @@ -275,6 +275,7 @@ public sealed class BSPrim : BSPhysObject { // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + ActivateIfPhysical(false); }); } } @@ -287,6 +288,7 @@ public sealed class BSPrim : BSPhysObject _position = value; PositionSanityCheck(); BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + ActivateIfPhysical(false); } } @@ -401,6 +403,7 @@ public sealed class BSPrim : BSPhysObject // 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); + ActivateIfPhysical(false); }); } } @@ -409,6 +412,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() { _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); + ActivateIfPhysical(false); }); } public override void VehicleVectorParam(int param, OMV.Vector3 value) @@ -416,6 +420,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() { _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); + ActivateIfPhysical(false); }); } public override void VehicleRotationParam(int param, OMV.Quaternion rotation) @@ -423,6 +428,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() { _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + ActivateIfPhysical(false); }); } public override void VehicleFlags(int param, bool remove) @@ -540,6 +546,8 @@ public sealed class BSPrim : BSPhysObject { // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); SetObjectDynamic(true); + // whether phys-to-static or static-to-phys, the object is not moving. + ZeroMotion(); }); } } @@ -623,7 +631,7 @@ public sealed class BSPrim : BSPhysObject // Become a Bullet 'static' object type CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement - BulletSimAPI.ClearAllForces2(BSBody.ptr); + ZeroMotion(); // Center of mass is at the center of the object BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation); // Mass is zero which disables a bunch of physics stuff in Bullet @@ -634,7 +642,7 @@ public sealed class BSPrim : BSPhysObject if (PhysicsScene.Params.ccdMotionThreshold > 0f) { BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } // There can be special things needed for implementing linksets Linkset.MakeStatic(this); @@ -656,14 +664,14 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.defaultRestitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 - BulletSimAPI.ClearAllForces2(BSBody.ptr); + // Since this can be called multiple times, only zero forces when becoming physical + // BulletSimAPI.ClearAllForces2(BSBody.ptr); // For good measure, make sure the transform is set through to the motion state BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); // A dynamic object has mass - IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); - OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Mass); + OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, Mass); BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); @@ -671,7 +679,7 @@ public sealed class BSPrim : BSPhysObject if (PhysicsScene.Params.ccdMotionThreshold > 0f) { BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } // Various values for simulation limits @@ -721,6 +729,15 @@ public sealed class BSPrim : BSPhysObject } } + // Enable physical actions. Bullet will keep sleeping non-moving physical objects so + // they need waking up when parameters are changed. + // Called in taint-time!! + private void ActivateIfPhysical(bool forceIt) + { + if (IsPhysical) + BulletSimAPI.Activate2(BSBody.ptr, forceIt); + } + // Turn on or off the flag controlling whether collision events are returned to the simulator. private void EnableCollisions(bool wantsCollisionEvents) { @@ -901,8 +918,7 @@ public sealed class BSPrim : BSPhysObject } m_accumulatedForces.Clear(); } - // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); - // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. + DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); }; @@ -912,9 +928,43 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.AddForce", addForceOperation); } + private List m_accumulatedAngularForces = new List(); public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { - // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); - // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); + AddAngularForce(force, pushforce, false); + } + public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) + { + if (force.IsFinite()) + { + // _force += force; + lock (m_accumulatedAngularForces) + m_accumulatedAngularForces.Add(new OMV.Vector3(force)); + } + else + { + m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } + BSScene.TaintCallback addAngularForceOperation = delegate() + { + OMV.Vector3 fSum = OMV.Vector3.Zero; + lock (m_accumulatedAngularForces) + { + // Sum the accumulated additional forces for one big force to apply once. + foreach (OMV.Vector3 v in m_accumulatedAngularForces) + { + fSum += v; + } + m_accumulatedAngularForces.Clear(); + } + // DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); + if (fSum != OMV.Vector3.Zero) + BulletSimAPI.ApplyTorque2(BSBody.ptr, fSum); + }; + if (inTaintTime) + addAngularForceOperation(); + else + PhysicsScene.TaintedObject("BSPrim.AddForce", addAngularForceOperation); } public override void SetMomentum(OMV.Vector3 momentum) { // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); -- cgit v1.1 From 2b75035aefceeae44e35364036a0748dfd5fb786 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Oct 2012 13:54:54 -0700 Subject: BulletSim: add ForEachMember(action) call for linkset. --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 36 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 24fe6b9..d0e514b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -167,9 +167,8 @@ public abstract class BSLinkset bool ret = false; lock (m_linksetActivityLock) { - if (m_children.Contains(child)) - ret = true; - /* + ret = m_children.Contains(child); + /* Safer version but the above should work foreach (BSPhysObject bp in m_children) { if (child.LocalID == bp.LocalID) @@ -183,6 +182,25 @@ public abstract class BSLinkset return ret; } + // Perform an action on each member of the linkset including root prim. + // The action is performed only on the objects that are physically in the linkset. + // Depends on the action on whether this should be done at taint time. + public delegate bool ForEachMemberAction(BSPhysObject obj); + public virtual bool ForEachMember(ForEachMemberAction action) + { + bool ret = false; + lock (m_linksetActivityLock) + { + action(LinksetRoot); + foreach (BSPhysObject po in m_taintChildren) + { + if (action(po)) + break; + } + } + return ret; + } + // When physical properties are changed the linkset needs to recalculate // its internal properties. // May be called at runtime or taint-time (just pass the appropriate flag). @@ -224,13 +242,15 @@ public abstract class BSLinkset protected virtual float ComputeLinksetMass() { - float mass; - lock (m_linksetActivityLock) + float mass = LinksetRoot.MassRaw; + if (HasAnyChildren) { - mass = LinksetRoot.MassRaw; - foreach (BSPhysObject bp in m_taintChildren) + lock (m_linksetActivityLock) { - mass += bp.MassRaw; + foreach (BSPhysObject bp in m_children) + { + mass += bp.MassRaw; + } } } return mass; -- cgit v1.1 From 92d3c611e57fc320bf20b6b500c275eaebf912aa Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Oct 2012 13:55:20 -0700 Subject: BulletSim: many small changes for vehicles simulation. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 71 ++++++++++++---------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 9b59bef..8bd8117 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -526,6 +526,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr); } */ + if (IsActive) + { + // Friction effects are handled by this vehicle code + BulletSimAPI.SetFriction2(Prim.BSBody.ptr, 0f); + BulletSimAPI.SetHitFraction2(Prim.BSBody.ptr, 0f); + } } // One step of the vehicle properties for the next 'pTimestep' seconds. @@ -552,6 +558,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.ForceOrientation = newOrientation; } */ + BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; @@ -570,17 +577,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 origDir = m_linearMotorDirection; Vector3 origVel = m_lastLinearVelocityVector; + Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG // add drive to body Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep); // lastLinearVelocityVector is the current body velocity vector m_lastLinearVelocityVector += addAmount; - float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep)); - m_linearMotorDirection *= keepfraction; + float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep; + m_linearMotorDirection *= (1f - decayFactor); - VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}", - Prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector); + Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; + m_lastLinearVelocityVector *= (Vector3.One - frictionFactor); + + VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},lmDir={6},lmVel={7}", + Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, m_linearMotorDirection, m_lastLinearVelocityVector); // convert requested object velocity to object relative vector m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; @@ -661,18 +672,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - float horizontalError = pos.Z - m_VhoverTargetHeight; + float verticalError = pos.Z - m_VhoverTargetHeight; // RA: where does the 50 come from> - float horizontalCorrectionVelocity = ((horizontalError * 50.0f) / (m_VhoverTimescale / pTimestep)); + float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); // Replace Vertical speed with correction figure if significant - if (Math.Abs(horizontalError) > 0.01f) + if (Math.Abs(verticalError) > 0.01f) { - m_newVelocity.Z += horizontalCorrectionVelocity; + m_newVelocity.Z += verticalCorrectionVelocity; //KF: m_VhoverEfficiency is not yet implemented } - else if (horizontalError < -0.01) + else if (verticalError < -0.01) { - m_newVelocity.Z -= horizontalCorrectionVelocity; + m_newVelocity.Z -= verticalCorrectionVelocity; } else { @@ -748,16 +759,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_flags & (VehicleFlag.NO_Z)) != 0) m_newVelocity.Z = 0; - // Apply friction - Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep)); - m_lastLinearVelocityVector *= keepFraction; - // Apply velocity - // Prim.ForceVelocity = m_newVelocity; - Prim.AddForce(m_newVelocity, false); + Prim.ForceVelocity = m_newVelocity; + // Prim.AddForce(m_newVelocity * Prim.Linkset.LinksetMass, false); + // Prim.AddForce(grav * Prim.Linkset.LinksetMass, false); - VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction); + VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4}", + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav); } // end MoveLinear() @@ -858,14 +866,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin #region Deflection //Forward is the prefered direction, but if the reference frame has changed, we need to take this into account as well - Vector3 PreferredAxisOfMotion = - new Vector3((10*(m_angularDeflectionEfficiency/m_angularDeflectionTimescale)), 0, 0); - PreferredAxisOfMotion *= Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); + if (m_angularDeflectionEfficiency != 0) + { + Vector3 preferredAxisOfMotion = + new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); + preferredAxisOfMotion *= Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); - //Multiply it so that it scales linearly - //deflection = PreferredAxisOfMotion; + deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; - //deflection = ((PreferredAxisOfMotion * m_angularDeflectionEfficiency) / (m_angularDeflectionTimescale / pTimestep)); + VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", + Prim.LocalID, preferredAxisOfMotion, deflection); + } #endregion @@ -917,18 +928,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin banking += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; + VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},banking={3}", + Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, banking); } #endregion m_lastVertAttractor = vertattr; - // Bank section tba - - // Deflection section tba - // Sum velocities - m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection + m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection; if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { @@ -948,8 +957,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; // Apply to the body - // Prim.ForceRotationalVelocity = m_lastAngularVelocity; - Prim.AddAngularForce(m_lastAngularVelocity, false); + // The above calculates the absolute angular velocity needed + Prim.ForceRotationalVelocity = m_lastAngularVelocity; VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity); } //end MoveAngular -- cgit v1.1 From 7af28724acf12245977fc44576c36ec0de320a8a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Oct 2012 16:09:08 -0700 Subject: BulletSim: rename constraint classes so they show up together alphabetically. --- .../Physics/BulletSPlugin/BS6DofConstraint.cs | 154 --------------------- .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 154 +++++++++++++++++++++ .../Physics/BulletSPlugin/BSConstraintHinge.cs | 57 ++++++++ .../Physics/BulletSPlugin/BSHingeConstraint.cs | 57 -------- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 +- 5 files changed, 212 insertions(+), 212 deletions(-) delete mode 100755 OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs delete mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs deleted file mode 100755 index ecb3ec8..0000000 --- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - -public sealed class BS6DofConstraint : BSConstraint -{ - private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; - - public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } - - // Create a btGeneric6DofConstraint - public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, - Vector3 frame1, Quaternion frame1rot, - Vector3 frame2, Quaternion frame2rot, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - frame1, frame1rot, - frame2, frame2rot, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - m_enabled = true; - world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - BSScene.DetailLogZero, world.worldID, - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); - } - - public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, - Vector3 joinPoint, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero) - { - world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - BSScene.DetailLogZero, world.worldID, - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); - world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - "[BULLETSIM 6DOF CONSTRAINT]", world.worldID, - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); - m_enabled = false; - } - else - { - m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - joinPoint, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", - BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); - if (m_constraint.ptr == IntPtr.Zero) - { - world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", - LogHeader, obj1.ID, obj2.ID); - m_enabled = false; - } - else - { - m_enabled = true; - } - } - } - - public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) - { - bool ret = false; - if (m_enabled) - { - BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); - ret = true; - } - return ret; - } - - public bool SetCFMAndERP(float cfm, float erp) - { - bool ret = false; - if (m_enabled) - { - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - ret = true; - } - return ret; - } - - public bool UseFrameOffset(bool useOffset) - { - bool ret = false; - float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; - if (m_enabled) - ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff); - return ret; - } - - public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce) - { - bool ret = false; - float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; - if (m_enabled) - { - ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce); - m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}", - BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce); - } - return ret; - } - - public bool SetBreakingImpulseThreshold(float threshold) - { - bool ret = false; - if (m_enabled) - ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); - return ret; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs new file mode 100755 index 0000000..3c37d76 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -0,0 +1,154 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public sealed class BSConstraint6Dof : BSConstraint +{ + private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; + + public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } + + // Create a btGeneric6DofConstraint + public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 frame1, Quaternion frame1rot, + Vector3 frame2, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + m_constraint = new BulletConstraint( + BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + frame1, frame1rot, + frame2, frame2rot, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + m_enabled = true; + world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", + BSScene.DetailLogZero, world.worldID, + obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + } + + public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero) + { + world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", + BSScene.DetailLogZero, world.worldID, + obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", + "[BULLETSIM 6DOF CONSTRAINT]", world.worldID, + obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + m_enabled = false; + } + else + { + m_constraint = new BulletConstraint( + BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + joinPoint, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", + BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), + obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + if (m_constraint.ptr == IntPtr.Zero) + { + world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", + LogHeader, obj1.ID, obj2.ID); + m_enabled = false; + } + else + { + m_enabled = true; + } + } + } + + public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); + ret = true; + } + return ret; + } + + public bool SetCFMAndERP(float cfm, float erp) + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); + BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + ret = true; + } + return ret; + } + + public bool UseFrameOffset(bool useOffset) + { + bool ret = false; + float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; + if (m_enabled) + ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff); + return ret; + } + + public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce) + { + bool ret = false; + float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; + if (m_enabled) + { + ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce); + m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}", + BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce); + } + return ret; + } + + public bool SetBreakingImpulseThreshold(float threshold) + { + bool ret = false; + if (m_enabled) + ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs new file mode 100755 index 0000000..ed3ffa7 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public sealed class BSConstraintHinge : BSConstraint +{ + public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } + + public BSConstraintHinge(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 pivotInA, Vector3 pivotInB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + m_constraint = new BulletConstraint( + BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + pivotInA, pivotInB, + axisInA, axisInB, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + m_enabled = true; + } + +} + +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs deleted file mode 100755 index 76bd930..0000000 --- a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - -public sealed class BSHingeConstraint : BSConstraint -{ - public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } - - public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, - Vector3 pivotInA, Vector3 pivotInB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - pivotInA, pivotInB, - axisInA, axisInB, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - m_enabled = true; - } - -} - -} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 003c294..67979b3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -246,7 +246,7 @@ public sealed class BSLinksetConstraints : BSLinkset // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 - BS6DofConstraint constrain = new BS6DofConstraint( + BSConstraint6Dof constrain = new BSConstraint6Dof( PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true ); /* NOTE: below is an attempt to build constraint with full frame computation, etc. -- cgit v1.1 From e20bad12cc0584c6368e46e0f326e6b616133e8f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 11:30:47 -0700 Subject: BulletSim: centralize mass/inertia computation with UpdatePhysicalMassProperties() function. Didn't add setMassRaw because assignment with side effect is dirty. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 15 ++++++--- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 2 ++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 39 ++++++++++++++-------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8bb4b21..b9013ab 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -155,8 +155,7 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); - BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); + UpdatePhysicalMassProperties(MassRaw); // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(BSBody.ptr, OMV.Vector3.Zero); @@ -201,8 +200,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); - BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); + UpdatePhysicalMassProperties(MassRaw); }); } @@ -329,7 +327,14 @@ public sealed class BSCharacter : BSPhysObject public override float Mass { get { return _mass; } } // used when we only want this prim's mass and not the linkset thing - public override float MassRaw { get {return _mass; } } + public override float MassRaw { + get {return _mass; } + } + public override void UpdatePhysicalMassProperties(float physMass) + { + OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass); + BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia); + } public override OMV.Vector3 Force { get { return _force; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 538f905..be8d64b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -64,6 +64,8 @@ public abstract class BSPhysObject : PhysicsActor // Return the object mass without calculating it or having side effects public abstract float MassRaw { get; } + // Set the raw mass but also update physical mass properties (inertia, ...) + public abstract void UpdatePhysicalMassProperties(float mass); // Reference to the physical body (btCollisionObject) of this object public BulletBody BSBody; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 44937df..ad09a61 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -356,13 +356,32 @@ public sealed class BSPrim : BSPhysObject { get { - // return Linkset.LinksetMass; - return _mass; + return Linkset.LinksetMass; + // return _mass; } } // used when we only want this prim's mass and not the linkset thing - public override float MassRaw { get { return _mass; } } + public override float MassRaw { + get { return _mass; } + } + // Set the physical mass to the passed mass. + // Note that this does not change _mass! + public override void UpdatePhysicalMassProperties(float physMass) + { + if (IsStatic) + { + BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); + BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); + } + else + { + OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass); + BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia); + BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, localInertia); + } + } // Is this used? public override OMV.Vector3 CenterOfMass @@ -613,7 +632,7 @@ public sealed class BSPrim : BSPhysObject // 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, true); + Linkset.Refresh(this); DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); @@ -635,9 +654,7 @@ public sealed class BSPrim : BSPhysObject // Center of mass is at the center of the object BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation); // Mass is zero which disables a bunch of physics stuff in Bullet - BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); - // There is no inertia in a static object - BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); + UpdatePhysicalMassProperties(0f); // Set collision detection parameters if (PhysicsScene.Params.ccdMotionThreshold > 0f) { @@ -671,9 +688,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); // A dynamic object has mass - OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, Mass); - BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); - BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); + UpdatePhysicalMassProperties(MassRaw); // Set collision detection parameters if (PhysicsScene.Params.ccdMotionThreshold > 0f) @@ -1247,9 +1262,7 @@ public sealed class BSPrim : BSPhysObject returnMass = _density * volume; - /* - * This change means each object keeps its own mass and the Mass property - * will return the sum if we're part of a linkset. + /* Comment out code that computes the mass of the linkset. That is done in the Linkset class. if (IsRootOfLinkset) { foreach (BSPrim prim in _childrenPrims) -- cgit v1.1 From 2f25f70316ff712d338bbff3f6d02650480a340b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 11:31:50 -0700 Subject: BulletSim: remove unneeded parameter from Refresh(). --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index d0e514b..569d2e7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -204,7 +204,7 @@ public abstract class BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. // May be called at runtime or taint-time (just pass the appropriate flag). - public abstract void Refresh(BSPhysObject requestor, bool inTaintTime); + public abstract void Refresh(BSPhysObject requestor); // The object is going dynamic (physical). Do any setup necessary // for a dynamic linkset. -- cgit v1.1 From 9568f24c2628312f366c99ce6beb5c193aace33c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 11:38:01 -0700 Subject: BulletSim: add post taint taints and post step taints. The post taints operation is most useful and is used by linksets to build and rebuild only once before the simulation step. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 138 +++++++++++++++++++++--- 1 file changed, 122 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 9e95ce5..cb52937 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -171,7 +171,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } private Object _taintLock = new Object(); // lock for using the next object - private List _taintedObjects; + private List _taintOperations; + private Dictionary _postTaintOperations; + private List _postStepOperations; // A pointer to an instance if this structure is passed to the C++ code // Used to pass basic configuration values to the unmanaged code. @@ -203,7 +205,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public override void Initialise(IMesher meshmerizer, IConfigSource config) { mesher = meshmerizer; - _taintedObjects = new List(); + _taintOperations = new List(); + _postTaintOperations = new Dictionary(); + _postStepOperations = new List(); PhysObjects = new Dictionary(); Shapes = new BSShapeCollection(this); @@ -475,23 +479,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (!m_initialized) return 5.0f; // update the prim states while we know the physics engine is not busy - int numTaints = _taintedObjects.Count; + int numTaints = _taintOperations.Count; ProcessTaints(); // Some of the prims operate with special vehicle properties ProcessVehicles(timeStep); - numTaints += _taintedObjects.Count; + numTaints += _taintOperations.Count; ProcessTaints(); // the vehicles might have added taints // step the physical world one interval m_simulationStep++; int numSubSteps = 0; - // DEBUG - // DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep); - try { + // DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -500,6 +502,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); + // DumpVehicles(); // DEBUG } catch (Exception e) { @@ -579,6 +582,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Only enable this in a limited test world with few objects. // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG + ProcessPostStepTaints(); + // 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. // We multiply by 55 to give a recognizable running rate (55 or less). @@ -670,6 +675,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public override bool IsThreaded { get { return false; } } + #region Taints + // Calls to the PhysicsActors can't directly call into the physics engine // because it might be busy. We delay changes to a known time. // We rely on C#'s closure to save and restore the context for the delegate. @@ -679,7 +686,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters lock (_taintLock) { - _taintedObjects.Add(new TaintCallbackEntry(ident, callback)); + _taintOperations.Add(new TaintCallbackEntry(ident, callback)); } return; @@ -690,19 +697,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // here just before the physics engine is called to step the simulation. public void ProcessTaints() { - if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process + ProcessRegularTaints(); + ProcessPostTaintTaints(); + } + + private void ProcessRegularTaints() + { + if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process { int taintCount = m_taintsToProcessPerStep; TaintCallbackEntry oneCallback = new TaintCallbackEntry(); - while (_taintedObjects.Count > 0 && taintCount-- > 0) + while (_taintOperations.Count > 0 && taintCount-- > 0) { bool gotOne = false; lock (_taintLock) { - if (_taintedObjects.Count > 0) + if (_taintOperations.Count > 0) { - oneCallback = _taintedObjects[0]; - _taintedObjects.RemoveAt(0); + oneCallback = _taintOperations[0]; + _taintOperations.RemoveAt(0); gotOne = true; } } @@ -746,6 +759,89 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } + // Schedule an update to happen after all the regular taints are processed. + // Note that new requests for the same operation ("ident") for the same object ("ID") + // will replace any previous operation by the same object. + public void PostTaintObject(String ident, uint ID, TaintCallback callback) + { + if (!m_initialized) return; + + lock (_taintLock) + { + _postTaintOperations[ident] = new TaintCallbackEntry(ident + "-" + ID.ToString(), callback); + } + + return; + } + + private void ProcessPostTaintTaints() + { + if (_postTaintOperations.Count > 0) + { + Dictionary oldList; + lock (_taintLock) + { + oldList = _postTaintOperations; + _postTaintOperations = new Dictionary(); + } + + foreach (KeyValuePair kvp in oldList) + { + try + { + DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG + kvp.Value.callback(); + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e); + } + } + oldList.Clear(); + } + } + + public void PostStepTaintObject(String ident, TaintCallback callback) + { + if (!m_initialized) return; + + lock (_taintLock) + { + _postStepOperations.Add(new TaintCallbackEntry(ident, callback)); + } + + return; + } + + private void ProcessPostStepTaints() + { + if (_postStepOperations.Count > 0) + { + List oldList; + lock (_taintLock) + { + oldList = _postStepOperations; + _postStepOperations = new List(); + } + + foreach (TaintCallbackEntry tcbe in oldList) + { + try + { + DetailLog("{0},BSScene.ProcessPostStepTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG + tcbe.callback(); + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: ProcessPostStepTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e); + } + } + oldList.Clear(); + } + } + + #endregion // Taints + #region Vehicles public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType) @@ -1006,7 +1102,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdSweptSphereRadius; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdSweepSphereRadius2(o.BSBody.ptr, v); } ), + (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.BSBody.ptr, v); } ), new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 0.1f, (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, @@ -1128,12 +1224,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", - 0.001f, + 0.1f, (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linkConstraintCFM; }, (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ), new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", - 0.8f, + 0.1f, (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linkConstraintERP; }, (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ), @@ -1326,6 +1422,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #endregion Runtime settable parameters + // Debugging routine for dumping detailed physical information for vehicle prims + private void DumpVehicles() + { + foreach (BSPrim prim in m_vehicles) + { + BulletSimAPI.DumpRigidBody2(World.ptr, prim.BSBody.ptr); + BulletSimAPI.DumpCollisionShape2(World.ptr, prim.BSShape.ptr); + } + } + // Invoke the detailed logger and output something if it's enabled. public void DetailLog(string msg, params Object[] args) { -- cgit v1.1 From 8c9e4c1f7bdde47c9f29a9dfcf917421b943bb32 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 11:41:25 -0700 Subject: BulletSim: Use Refresh/PostTaints to cause recomputing of constraint variables before the simulation step. Update logging and messages to properly name LinksetConstraints. Use UpdatePhysicalMassProperties to put the whole linkset mass into all the physical linkset members so they have the inertia to move the whole linkset. --- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 65 ++++++++++++---------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 67979b3..086aa12 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -43,23 +43,20 @@ public sealed class BSLinksetConstraints : BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. - // May be called at runtime or taint-time (just pass the appropriate flag). - public override void Refresh(BSPhysObject requestor, bool inTaintTime) + // This is queued in such a way that the + // refresh will only happen once after all the other taints are applied. + public override void Refresh(BSPhysObject requestor) { - // If there are no children or not root, I am not the one that recomputes the constraints - if (!HasAnyChildren || !IsRoot(requestor)) + // If there are no children, there are no constraints to recompute. + if (!HasAnyChildren) return; - BSScene.TaintCallback refreshOperation = delegate() + // Queue to happen after all the other taint processing + PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() { RecomputeLinksetConstraintVariables(); - DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}", - LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); - }; - if (inTaintTime) - refreshOperation(); - else - PhysicsScene.TaintedObject("BSLinkSet.Refresh", refreshOperation); + }); + } // The object is going dynamic (physical). Do any setup necessary @@ -104,14 +101,14 @@ public sealed class BSLinksetConstraints : BSLinkset if (IsRoot(child)) { // If the one with the dependency is root, must undo all children - DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", + DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); } else { - DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}", + DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}", child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), child.LocalID, child.BSBody.ptr.ToString("X")); @@ -132,7 +129,7 @@ public sealed class BSLinksetConstraints : BSLinkset { if (IsRoot(child)) { - DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}", + DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}", child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count); foreach (BSPhysObject bpo in m_taintChildren) { @@ -141,7 +138,7 @@ public sealed class BSLinksetConstraints : BSLinkset } else { - DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}", + DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}", LinksetRoot.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), child.LocalID, child.BSBody.ptr.ToString("X")); @@ -178,6 +175,7 @@ public sealed class BSLinksetConstraints : BSLinkset PhysicallyLinkAChildToRoot(rootx, childx); m_taintChildren.Add(child); }); + Refresh(LinksetRoot); } return; } @@ -211,9 +209,9 @@ public sealed class BSLinksetConstraints : BSLinkset { m_taintChildren.Remove(child); PhysicallyUnlinkAChildFromRoot(rootx, childx); - RecomputeLinksetConstraintVariables(); }); - + // See that the linkset parameters are recomputed at the end of the taint time. + Refresh(LinksetRoot); } else { @@ -237,7 +235,7 @@ public sealed class BSLinksetConstraints : BSLinkset // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); - DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", + DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), @@ -248,6 +246,7 @@ public sealed class BSLinksetConstraints : BSLinkset BSConstraint6Dof constrain = new BSConstraint6Dof( PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true ); + // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); /* NOTE: below is an attempt to build constraint with full frame computation, etc. * Using the midpoint is easier since it lets the Bullet code manipulate the transforms @@ -264,7 +263,7 @@ public sealed class BSLinksetConstraints : BSLinkset // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 - DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); + DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( PhysicsScene.World, rootPrim.Body, childPrim.Body, OMV.Vector3.Zero, @@ -307,7 +306,7 @@ public sealed class BSLinksetConstraints : BSLinkset private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) { bool ret = false; - DetailLog("{0},BSLinkset.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", + DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), childPrim.LocalID, childPrim.BSBody.ptr.ToString("X")); @@ -327,7 +326,7 @@ public sealed class BSLinksetConstraints : BSLinkset // Called at taint time! private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) { - DetailLog("{0},BSLinkset.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); + DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); bool ret = false; if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody)) @@ -350,7 +349,7 @@ public sealed class BSLinksetConstraints : BSLinkset BSConstraint constrain; if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) { - // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", + // DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); constrain.RecomputeConstraintVariables(linksetMass); } @@ -367,15 +366,23 @@ public sealed class BSLinksetConstraints : BSLinkset { // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); - BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, - centerOfMass, OMV.Quaternion.Identity); - DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2}", - LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X")); + BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); + // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2},linksetMass={3}", + LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); foreach (BSPhysObject child in m_taintChildren) { - BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, - centerOfMass, OMV.Quaternion.Identity); + BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); + // A child in the linkset physically shows the mass of the whole linkset. + // This allows Bullet to apply enough force on the child to move the whole linkset. + child.UpdatePhysicalMassProperties(linksetMass); + // DEBUG: see of inter-linkset collisions are causing problems + // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); } + // Also update the root's physical mass to the whole linkset + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG } -- cgit v1.1 From bc43c7007d3d8ffc2f497a6d37004eb3d3544e00 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 14:27:48 -0700 Subject: BulletSim: code rearrangement --- OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs | 12 ++++++------ .../Region/Physics/BulletSPlugin/BSConstraintCollection.cs | 2 -- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index f017cdd..65fac00 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -42,6 +42,12 @@ public abstract class BSConstraint : IDisposable protected BulletConstraint m_constraint; protected bool m_enabled = false; + public BulletBody Body1 { get { return m_body1; } } + public BulletBody Body2 { get { return m_body2; } } + public BulletConstraint Constraint { get { return m_constraint; } } + public abstract ConstraintType Type { get; } + public bool IsEnabled { get { return m_enabled; } } + public BSConstraint() { } @@ -64,12 +70,6 @@ public abstract class BSConstraint : IDisposable } } - public BulletBody Body1 { get { return m_body1; } } - public BulletBody Body2 { get { return m_body2; } } - public BulletConstraint Constraint { get { return m_constraint; } } - public abstract ConstraintType Type { get; } - - public virtual bool SetLinearLimits(Vector3 low, Vector3 high) { bool ret = false; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs index b9add06..a9fd826 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -143,8 +143,6 @@ public sealed class BSConstraintCollection : IDisposable // Return 'true' if any constraints were destroyed. public bool RemoveAndDestroyConstraint(BulletBody body1) { - // return BulletSimAPI.RemoveConstraintByID(m_world.ID, obj.ID); - List toRemove = new List(); uint lookingID = body1.ID; lock (m_constraints) -- cgit v1.1 From 4cfa3be4efbca49e4670b92ec2c110f65f658b8e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 14:28:24 -0700 Subject: BulletSim: add definitions for linkset collision mask --- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index be3a5ad..9b7ba03 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -378,6 +378,7 @@ public enum CollisionFilterGroups : uint BTerrainFilter = 1 << 11, BRaycastFilter = 1 << 12, BSolidFilter = 1 << 13, + BLinksetFilter = 1 << 14, // The collsion filters and masked are defined in one place -- don't want them scattered AvatarFilter = BCharacterFilter, @@ -386,6 +387,8 @@ public enum CollisionFilterGroups : uint ObjectMask = BAllFilter, StaticObjectFilter = BStaticFilter, StaticObjectMask = BAllFilter, + LinksetFilter = BLinksetFilter, + LinksetMask = BAllFilter & ~BLinksetFilter, VolumeDetectFilter = BSensorTrigger, VolumeDetectMask = ~BSensorTrigger, TerrainFilter = BTerrainFilter, -- cgit v1.1 From dae038a117c3110970d6fe0b743e20f342df2269 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 14:30:16 -0700 Subject: BulletSim: fix problem with multiple linksets stepping on each other if they are built at the same time. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index cb52937..c27b5f0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -578,12 +578,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } + ProcessPostStepTaints(); + // This causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG - ProcessPostStepTaints(); - // 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. // We multiply by 55 to give a recognizable running rate (55 or less). @@ -766,9 +766,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { if (!m_initialized) return; + string uniqueIdent = ident + "-" + ID.ToString(); lock (_taintLock) { - _postTaintOperations[ident] = new TaintCallbackEntry(ident + "-" + ID.ToString(), callback); + _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback); } return; -- cgit v1.1 From 42d65840c843f2cac6f02fc1b6012140c9cb240e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 14:32:07 -0700 Subject: BulletSim: Add gravity force to vehicle. Some debugging additions. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 8bd8117..4981007 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -539,6 +539,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; + m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time + MoveLinear(pTimestep); MoveAngular(pTimestep); LimitRotation(pTimestep); @@ -558,7 +560,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.ForceOrientation = newOrientation; } */ - BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); + // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. + BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; @@ -762,13 +765,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Apply velocity Prim.ForceVelocity = m_newVelocity; // Prim.AddForce(m_newVelocity * Prim.Linkset.LinksetMass, false); - // Prim.AddForce(grav * Prim.Linkset.LinksetMass, false); + Prim.AddForce(grav * Prim.Linkset.LinksetMass, false); VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4}", Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav); } // end MoveLinear() + // ======================================================================= // Apply the effect of the angular motor. private void MoveAngular(float pTimestep) { -- cgit v1.1 From 93fe384cce42e91337f446fd658ef29ca3d9f733 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Oct 2012 14:33:31 -0700 Subject: BulletSim: Use the PostTaints operation to build the linkset once before the next simulation step. This eliminates the management of children vs taintChildren and simplifies the constratin creation code. --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 52 +++----- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 140 +++++++-------------- 2 files changed, 68 insertions(+), 124 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 569d2e7..187951e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -61,16 +61,7 @@ public abstract class BSLinkset public int LinksetID { get; private set; } // The children under the root in this linkset. - // There are two lists of children: the current children at runtime - // and the children at taint-time. For instance, if you delink a - // child from the linkset, the child is removed from m_children - // but the constraint won't be removed until taint time. - // Two lists lets this track the 'current' children and - // the physical 'taint' children separately. - // After taint processing and before the simulation step, these - // two lists must be the same. protected HashSet m_children; - protected HashSet m_taintChildren; // We lock the diddling of linkset classes to prevent any badness. // This locks the modification of the instances of this class. Changes @@ -110,7 +101,6 @@ public abstract class BSLinkset PhysicsScene = scene; LinksetRoot = parent; m_children = new HashSet(); - m_taintChildren = new HashSet(); m_mass = parent.MassRaw; } @@ -192,7 +182,7 @@ public abstract class BSLinkset lock (m_linksetActivityLock) { action(LinksetRoot); - foreach (BSPhysObject po in m_taintChildren) + foreach (BSPhysObject po in m_children) { if (action(po)) break; @@ -201,9 +191,24 @@ public abstract class BSLinkset return ret; } + // I am the root of a linkset and a new child is being added + // Called while LinkActivity is locked. + protected abstract void AddChildToLinkset(BSPhysObject child); + + // Forcefully removing a child from a linkset. + // This is not being called by the child so we have to make sure the child doesn't think + // it's still connected to the linkset. + // Normal OpenSimulator operation will never do this because other SceneObjectPart information + // also has to be updated (like pointer to prim's parent). + protected abstract void RemoveChildFromOtherLinkset(BSPhysObject pchild); + + // I am the root of a linkset and one of my children is being removed. + // Safe to call even if the child is not really in my linkset. + protected abstract void RemoveChildFromLinkset(BSPhysObject child); + // When physical properties are changed the linkset needs to recalculate // its internal properties. - // May be called at runtime or taint-time (just pass the appropriate flag). + // May be called at runtime or taint-time. public abstract void Refresh(BSPhysObject requestor); // The object is going dynamic (physical). Do any setup necessary @@ -238,8 +243,6 @@ public abstract class BSLinkset public abstract void RestoreBodyDependencies(BSPrim child); // ================================================================ - // Below this point is internal magic - protected virtual float ComputeLinksetMass() { float mass = LinksetRoot.MassRaw; @@ -264,7 +267,7 @@ public abstract class BSLinkset com = LinksetRoot.Position * LinksetRoot.MassRaw; float totalMass = LinksetRoot.MassRaw; - foreach (BSPhysObject bp in m_taintChildren) + foreach (BSPhysObject bp in m_children) { com += bp.Position * bp.MassRaw; totalMass += bp.MassRaw; @@ -283,31 +286,16 @@ public abstract class BSLinkset { com = LinksetRoot.Position; - foreach (BSPhysObject bp in m_taintChildren) + foreach (BSPhysObject bp in m_children) { com += bp.Position * bp.MassRaw; } - com /= (m_taintChildren.Count + 1); + com /= (m_children.Count + 1); } return com; } - // I am the root of a linkset and a new child is being added - // Called while LinkActivity is locked. - protected abstract void AddChildToLinkset(BSPhysObject child); - - // Forcefully removing a child from a linkset. - // This is not being called by the child so we have to make sure the child doesn't think - // it's still connected to the linkset. - // Normal OpenSimulator operation will never do this because other SceneObjectPart information - // also has to be updated (like pointer to prim's parent). - protected abstract void RemoveChildFromOtherLinkset(BSPhysObject pchild); - - // I am the root of a linkset and one of my children is being removed. - // Safe to call even if the child is not really in my linkset. - protected abstract void RemoveChildFromLinkset(BSPhysObject child); - // Invoke the detailed logger and output something if it's enabled. protected void DetailLog(string msg, params Object[] args) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 086aa12..6c1fa2a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -54,7 +54,7 @@ public sealed class BSLinksetConstraints : BSLinkset // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() { - RecomputeLinksetConstraintVariables(); + RecomputeLinksetConstraints(); }); } @@ -98,24 +98,13 @@ public sealed class BSLinksetConstraints : BSLinkset lock (m_linksetActivityLock) { - if (IsRoot(child)) - { - // If the one with the dependency is root, must undo all children - DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); + // Just undo all the constraints for this linkset. Rebuild at the end of the step. + DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); - ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); - } - else - { - DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}", - child.LocalID, - LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), - child.LocalID, child.BSBody.ptr.ToString("X")); - // ret = PhysicallyUnlinkAChildFromRoot(LinksetRoot, child); - // Despite the function name, this removes any link to the specified object. - ret = PhysicallyUnlinkAllChildrenFromRoot(child); - } + ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); + // Cause the constraints, et al to be rebuilt before the next simulation step. + Refresh(LinksetRoot); } return ret; } @@ -125,26 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset // Called at taint-time!! public override void RestoreBodyDependencies(BSPrim child) { - lock (m_linksetActivityLock) - { - if (IsRoot(child)) - { - DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}", - child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count); - foreach (BSPhysObject bpo in m_taintChildren) - { - PhysicallyLinkAChildToRoot(LinksetRoot, bpo); - } - } - else - { - DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}", - LinksetRoot.LocalID, - LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), - child.LocalID, child.BSBody.ptr.ToString("X")); - PhysicallyLinkAChildToRoot(LinksetRoot, child); - } - } + // The Refresh operation will build any missing constraints. } // ================================================================ @@ -163,18 +133,7 @@ public sealed class BSLinksetConstraints : BSLinkset DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); - PhysicsScene.TaintedObject("AddChildToLinkset", delegate() - { - DetailLog("{0},AddChildToLinkset,taint,rID={1},rBody={2},cID={3},cBody={4}", - rootx.LocalID, - rootx.LocalID, rootx.BSBody.ptr.ToString("X"), - childx.LocalID, childx.BSBody.ptr.ToString("X")); - // Since this is taint-time, the body and shape could have changed for the child - rootx.ForcePosition = rootx.Position; // DEBUG - childx.ForcePosition = childx.Position; // DEBUG - PhysicallyLinkAChildToRoot(rootx, childx); - m_taintChildren.Add(child); - }); + // Cause constraints and assorted properties to be recomputed before the next simulation step. Refresh(LinksetRoot); } return; @@ -207,7 +166,6 @@ public sealed class BSLinksetConstraints : BSLinkset PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() { - m_taintChildren.Remove(child); PhysicallyUnlinkAChildFromRoot(rootx, childx); }); // See that the linkset parameters are recomputed at the end of the taint time. @@ -225,6 +183,12 @@ public sealed class BSLinksetConstraints : BSLinkset // Called at taint time! private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) { + // Don't build the constraint when asked. Put it off until just before the simulation step. + Refresh(rootPrim); + } + + private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) + { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(); @@ -235,7 +199,7 @@ public sealed class BSLinksetConstraints : BSLinkset // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); - DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", + DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), @@ -297,6 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset { constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); } + return constrain; } // Remove linkage between myself and a particular child @@ -337,56 +302,47 @@ public sealed class BSLinksetConstraints : BSLinkset } // Call each of the constraints that make up this linkset and recompute the - // various transforms and variables. Used when objects are added or removed - // from a linkset to make sure the constraints know about the new mass and - // geometry. + // various transforms and variables. Create constraints of not created yet. + // Called before the simulation step to make sure the constraint based linkset + // is all initialized. // Must only be called at taint time!! - private void RecomputeLinksetConstraintVariables() + private void RecomputeLinksetConstraints() { float linksetMass = LinksetMass; - foreach (BSPhysObject child in m_taintChildren) + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + + // For a multiple object linkset, set everybody's center of mass to the set's center of mass + OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); + BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); + + // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,setCenterOfMass,COM={1},rBody={2},linksetMass={3}", + LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); + + foreach (BSPhysObject child in m_children) { + // A child in the linkset physically shows the mass of the whole linkset. + // This allows Bullet to apply enough force on the child to move the whole linkset. + // (Also do the mass stuff before recomputing the constraint so mass is not zero.) + BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); + child.UpdatePhysicalMassProperties(linksetMass); + BSConstraint constrain; - if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) - { - // DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", - // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); - constrain.RecomputeConstraintVariables(linksetMass); - } - else + if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) { - // Non-fatal error that happens when children are being added to the linkset but - // their constraints have not been created yet. - break; + // If constraint doesn't exist yet, create it. + constrain = BuildConstraint(LinksetRoot, child); } - } + constrain.RecomputeConstraintVariables(linksetMass); - // If the whole linkset is not here, doesn't make sense to recompute linkset wide values - if (m_children.Count == m_taintChildren.Count) - { - // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass - OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); - BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); - // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2},linksetMass={3}", - LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); - foreach (BSPhysObject child in m_taintChildren) - { - BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); - // A child in the linkset physically shows the mass of the whole linkset. - // This allows Bullet to apply enough force on the child to move the whole linkset. - child.UpdatePhysicalMassProperties(linksetMass); - // DEBUG: see of inter-linkset collisions are causing problems - // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - } - // Also update the root's physical mass to the whole linkset - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + // DEBUG: see of inter-linkset collisions are causing problems + // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG + // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG } - return; + } } } -- cgit v1.1 From 52be581f71b3c8da6113e4f4b193694683e6f8cc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 30 Oct 2012 09:12:07 -0700 Subject: BulletSim: remove center-of-mass setting for linksets because it causes the constraint calculation to pull the objects together. --- .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 3 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 1 - .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 79 ++++++++-------------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- 5 files changed, 33 insertions(+), 54 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs index 3c37d76..23ef052 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -71,8 +71,7 @@ public sealed class BSConstraint6Dof : BSConstraint BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - "[BULLETSIM 6DOF CONSTRAINT]", world.worldID, - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + LogHeader, world.worldID, obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); m_enabled = false; } else diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 187951e..6d84fcc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -132,7 +132,6 @@ public abstract class BSLinkset // Cannot remove the root from a linkset. return this; } - RemoveChildFromLinkset(child); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 6c1fa2a..ecb6ad4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -43,20 +43,16 @@ public sealed class BSLinksetConstraints : BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. - // This is queued in such a way that the - // refresh will only happen once after all the other taints are applied. + // This is queued in the 'post taint' queue so the + // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { - // If there are no children, there are no constraints to recompute. - if (!HasAnyChildren) - return; - // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() { - RecomputeLinksetConstraints(); + if (HasAnyChildren && IsRoot(requestor)) + RecomputeLinksetConstraints(); }); - } // The object is going dynamic (physical). Do any setup necessary @@ -71,9 +67,10 @@ public sealed class BSLinksetConstraints : BSLinkset return false; } - // The object is going static (non-physical). Do any setup necessary - // for a static linkset. + // The object is going static (non-physical). Do any setup necessary for a static linkset. // Return 'true' if any properties updated on the passed object. + // This doesn't normally happen -- OpenSim removes the objects from the physical + // world if it is a static linkset. // Called at taint-time! public override bool MakeStatic(BSPhysObject child) { @@ -87,21 +84,21 @@ public sealed class BSLinksetConstraints : BSLinkset // Nothing to do for constraints on property updates } - // Routine used when rebuilding the body of the root of the linkset - // Destroy all the constraints have have been made to root. - // This is called when the root body is changing. - // Returns 'true' of something eas actually removed and would need restoring + // Routine called when rebuilding the body of some member of the linkset. + // Destroy all the constraints have have been made to root and set + // up to rebuild the constraints before the next simulation step. + // Returns 'true' of something was actually removed and would need restoring // Called at taint-time!! public override bool RemoveBodyDependencies(BSPrim child) { bool ret = false; + DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); + lock (m_linksetActivityLock) { // Just undo all the constraints for this linkset. Rebuild at the end of the step. - DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); - ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); // Cause the constraints, et al to be rebuilt before the next simulation step. Refresh(LinksetRoot); @@ -114,13 +111,12 @@ public sealed class BSLinksetConstraints : BSLinkset // Called at taint-time!! public override void RestoreBodyDependencies(BSPrim child) { - // The Refresh operation will build any missing constraints. + // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. } // ================================================================ - // Below this point is internal magic - // I am the root of a linkset and a new child is being added + // Add a new child to the linkset. // Called while LinkActivity is locked. protected override void AddChildToLinkset(BSPhysObject child) { @@ -131,7 +127,7 @@ public sealed class BSLinksetConstraints : BSLinkset BSPhysObject rootx = LinksetRoot; // capture the root as of now BSPhysObject childx = child; - DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); + DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); // Cause constraints and assorted properties to be recomputed before the next simulation step. Refresh(LinksetRoot); @@ -150,7 +146,7 @@ public sealed class BSLinksetConstraints : BSLinkset RemoveChildFromLinkset(pchild); } - // I am the root of a linkset and one of my children is being removed. + // Remove the specified child from the linkset. // Safe to call even if the child is not really in my linkset. protected override void RemoveChildFromLinkset(BSPhysObject child) { @@ -159,12 +155,12 @@ public sealed class BSLinksetConstraints : BSLinkset BSPhysObject rootx = LinksetRoot; // capture the root and body as of now BSPhysObject childx = child; - DetailLog("{0},RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", + DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", childx.LocalID, rootx.LocalID, rootx.BSBody.ptr.ToString("X"), childx.LocalID, childx.BSBody.ptr.ToString("X")); - PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() + PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() { PhysicallyUnlinkAChildFromRoot(rootx, childx); }); @@ -173,7 +169,7 @@ public sealed class BSLinksetConstraints : BSLinkset } else { - // This will happen if we remove the root of the linkset first. Non-fatal occurance. + // Non-fatal occurance. // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); } return; @@ -215,7 +211,7 @@ public sealed class BSLinksetConstraints : BSLinkset /* NOTE: below is an attempt to build constraint with full frame computation, etc. * Using the midpoint is easier since it lets the Bullet code manipulate the transforms * of the objects. - * Code left as a warning to future programmers. + * Code left for future programmers. // ================================================================================== // relative position normalized to the root prim OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); @@ -225,8 +221,6 @@ public sealed class BSLinksetConstraints : BSLinkset OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); - // create a constraint that allows no freedom of movement between the two objects - // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( PhysicsScene.World, rootPrim.Body, childPrim.Body, @@ -234,11 +228,6 @@ public sealed class BSLinksetConstraints : BSLinkset OMV.Quaternion.Inverse(rootPrim.Orientation), OMV.Vector3.Zero, OMV.Quaternion.Inverse(childPrim.Orientation), - // A point half way between the parent and child - // childRelativePosition/2, - // childRelativeRotation, - // childRelativePosition/2, - // inverseChildRelativeRotation, true, true ); @@ -264,9 +253,9 @@ public sealed class BSLinksetConstraints : BSLinkset return constrain; } - // Remove linkage between myself and a particular child + // Remove linkage between the linkset root and a particular child // The root and child bodies are passed in because we need to remove the constraint between - // the bodies that were at unlink time. + // the bodies that were present at unlink time. // Called at taint time! private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) { @@ -288,44 +277,36 @@ public sealed class BSLinksetConstraints : BSLinkset } // Remove linkage between myself and any possible children I might have. + // Returns 'true' of any constraints were destroyed. // Called at taint time! private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) { DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); - bool ret = false; - if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody)) - { - ret = true; - } - return ret; + return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); } // Call each of the constraints that make up this linkset and recompute the // various transforms and variables. Create constraints of not created yet. // Called before the simulation step to make sure the constraint based linkset // is all initialized. - // Must only be called at taint time!! + // Called at taint time!! private void RecomputeLinksetConstraints() { float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass); - // For a multiple object linkset, set everybody's center of mass to the set's center of mass - OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); - BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); - + // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,setCenterOfMass,COM={1},rBody={2},linksetMass={3}", - LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); + DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,setCenterOfMass,rBody={1},linksetMass={2}", + LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); foreach (BSPhysObject child in m_children) { // A child in the linkset physically shows the mass of the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset. // (Also do the mass stuff before recomputing the constraint so mass is not zero.) - BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); child.UpdatePhysicalMassProperties(linksetMass); BSConstraint constrain; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index ad09a61..7851a40 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -634,7 +634,7 @@ public sealed class BSPrim : BSPhysObject // had been automatically disabled when the mass was set to zero. Linkset.Refresh(this); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", + DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 1c0e6f5..1219fc0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -109,7 +109,7 @@ public sealed class BSShapeCollection : IDisposable prim.BSShape, shapeData, bodyCallback); ret = newGeom || newBody; } - DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}", + DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", prim.LocalID, forceRebuild, ret, prim.BSBody, prim.BSShape); return ret; -- cgit v1.1 From 28e2cd3fa21835b124552dec024745f5784f6b3a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 31 Oct 2012 09:26:58 -0700 Subject: BulletSim: vehicle tweeking. Add AddTorque() method to BSPrim. Remove some manual motor actions in computing angular force (will eventually be replaced with motor class). Remove some experimental changes. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 136 ++++++++------------- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 45 +++++-- 3 files changed, 90 insertions(+), 93 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 4981007..5c61774 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -511,21 +511,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Do any updating needed for a vehicle public void Refresh() { - /* - * Doesnt work unless BSDynamics senses and corrects for all collisions - if (IsActive) - BulletSimAPI.AddToCollisionFlags2(Prim.BSBody.ptr, CollisionFlags.CF_KINEMATIC_OBJECT); - else - BulletSimAPI.RemoveFromCollisionFlags2(Prim.BSBody.ptr, CollisionFlags.CF_KINEMATIC_OBJECT); - */ - /* - * Doesn't work because with zero inertia, Bullet will not apply any forces to the object. - if (IsActive) - { - BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, Vector3.Zero); - BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr); - } - */ if (IsActive) { // Friction effects are handled by this vehicle code @@ -539,29 +524,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; - m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time + // DEBUG + // Because Bullet does apply forces to the vehicle, our last computed + // linear and angular velocities are not what is happening now. + // Vector3 externalAngularVelocity = Prim.ForceRotationalVelocity - m_lastAngularVelocity; + // m_lastAngularVelocity += (externalAngularVelocity * 0.5f) * pTimestep; + // m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time + // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG: + // END DEBUG MoveLinear(pTimestep); MoveAngular(pTimestep); LimitRotation(pTimestep); - /* Experimental - // Wonder if Bullet could handle collision penetration while this applies the forces. - // Apply the computed forces on the vehicle - Prim.ForcePosition += Prim.ForceVelocity * Prim.MassRaw * pTimestep; - - if (Prim.ForceRotationalVelocity != Vector3.Zero) - { - Quaternion newOrientation = Prim.ForceOrientation; - newOrientation.Normalize(); - Quaternion appliedRotation = new Quaternion((Prim.ForceRotationalVelocity * pTimestep), 0f); - newOrientation += (appliedRotation * newOrientation) * 0.5f; - newOrientation.Normalize(); - Prim.ForceOrientation = newOrientation; - } - */ // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. - BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG + // BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; @@ -583,7 +560,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG // add drive to body - Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep); + Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; // lastLinearVelocityVector is the current body velocity vector m_lastLinearVelocityVector += addAmount; @@ -593,11 +570,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; m_lastLinearVelocityVector *= (Vector3.One - frictionFactor); - VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},lmDir={6},lmVel={7}", - Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, m_linearMotorDirection, m_lastLinearVelocityVector); - - // convert requested object velocity to object relative vector + // Rotate new object velocity from vehicle relative to world coordinates m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; + + VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lmVel={8},newVel={9}", + Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor, + m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity); } else { @@ -609,18 +587,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); } - // m_newVelocity is velocity computed from linear motor + // m_newVelocity is velocity computed from linear motor in world coordinates - // Add the various forces into m_dir which will be our new direction vector (velocity) - - // add Gravity and Buoyancy + // 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 = Prim.PhysicsScene.DefaultGravity * (Prim.Linkset.LinksetMass * (1f - m_VehicleBuoyancy)); Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); /* - * RA: Not sure why one would do this + * RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ... // Preserve the current Z velocity Vector3 vel_now = m_prim.Velocity; m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity @@ -676,7 +651,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin else { float verticalError = pos.Z - m_VhoverTargetHeight; - // RA: where does the 50 come from> + // RA: where does the 50 come from? float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); // Replace Vertical speed with correction figure if significant if (Math.Abs(verticalError) > 0.01f) @@ -784,37 +759,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_angularFrictionTimescale // body angular velocity decay rate // m_lastAngularVelocity // what was last applied to body - // Get what the body is doing, this includes 'external' influences - Vector3 angularVelocity = Prim.ForceRotationalVelocity; - - if (m_angularMotorApply > 0) + if (m_angularMotorDirection.LengthSquared() > 0.0001) { - // Rather than snapping the angular motor velocity from the old value to - // a newly set velocity, this routine steps the value from the previous - // value (m_angularMotorVelocity) to the requested value (m_angularMotorDirection). - // There are m_angularMotorApply steps. Vector3 origVel = m_angularMotorVelocity; Vector3 origDir = m_angularMotorDirection; - // ramp up to new value // new velocity += error / ( time to get there / step interval) // requested speed - last motor speed m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); + // decay requested direction + m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); - VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},origDir={5},vel={6}", - Prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); - - m_angularMotorApply--; + VDetailLog("{0},MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", + Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); } else { - // No motor recently applied, keep the body velocity - // and decay the velocity - if (m_angularMotorVelocity.LengthSquared() < 0.0001) - m_angularMotorVelocity = Vector3.Zero; - else - m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); - } // end motor section + m_angularMotorVelocity = Vector3.Zero; + } #region Vertical attactor @@ -824,22 +786,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) { - float VAservo = 0.2f; + float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; if (Prim.Linkset.LinksetIsColliding) - VAservo = 0.05f / (m_verticalAttractionTimescale / pTimestep); + VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - // get present body rotation - Quaternion rotq = Prim.ForceOrientation; - // vector pointing up - Vector3 verticalError = Vector3.UnitZ; - - // rotate it to Body Angle - verticalError = verticalError * rotq; - // verticalError.X and .Y are the World error amounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. - // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go - // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. + // Create a vector of the vehicle "up" in world coordinates + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + // verticalError.X and .Y are the World error amounts. They are 0 when there is no + // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its + // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall + // and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be + // modulated to prevent a stable inverted body. // Error is 0 (no error) to +/- 2 (max error) if (verticalError.Z < 0.0f) @@ -850,13 +809,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin // scale it by VAservo verticalError = verticalError * VAservo; - // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y then .X increases, so - // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. + // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y + // then .X increases, so change Body angular velocity X based on Y, and Y based on X. + // Z is not changed. vertattr.X = verticalError.Y; vertattr.Y = - verticalError.X; vertattr.Z = 0f; // scaling appears better usingsquare-law + Vector3 angularVelocity = Prim.ForceRotationalVelocity; float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); vertattr.X += bounce * angularVelocity.X; vertattr.Y += bounce * angularVelocity.Y; @@ -956,15 +917,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); } - // apply friction - Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); - m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; - // Apply to the body // The above calculates the absolute angular velocity needed - Prim.ForceRotationalVelocity = m_lastAngularVelocity; + // Prim.ForceRotationalVelocity = m_lastAngularVelocity; + + // Apply a force to overcome current angular velocity + Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity) * Prim.Linkset.LinksetMass; + // Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity); + // Prim.AddAngularForce(applyAngularForce, false); + Prim.ApplyTorqueImpulse(applyAngularForce, false); + + // Apply friction for next time + Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep; + m_lastAngularVelocity *= Vector3.One - decayamount; - VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity); + VDetailLog("{0},MoveAngular,done,applyAForce={1},decay={2},lastAngular={3}", + Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity); } //end MoveAngular internal void LimitRotation(float timestep) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index ecb6ad4..8cdbd9b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -299,7 +299,7 @@ public sealed class BSLinksetConstraints : BSLinkset // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,setCenterOfMass,rBody={1},linksetMass={2}", + DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); foreach (BSPhysObject child in m_children) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 7851a40..9ced61fa 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -378,7 +378,9 @@ public sealed class BSPrim : BSPhysObject { OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass); BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia); - BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); + // center of mass is at the zero of the object + BulletSimAPI.SetCenterOfMassByPosRot2(BSBody.ptr, ForcePosition, ForceOrientation); + // BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, localInertia); } } @@ -462,9 +464,16 @@ public sealed class BSPrim : BSPhysObject // Called from Scene when doing simulation step so we're in taint processing time. public override void StepVehicle(float timeStep) { - if (IsPhysical) + if (IsPhysical && _vehicle.IsActive) { _vehicle.Step(timeStep); + /* // TEST TEST DEBUG DEBUG -- trying to reduce the extra action of Bullet simulation step + PhysicsScene.PostTaintObject("BSPrim.StepVehicles", LocalID, delegate() + { + // This resets the interpolation values and recomputes the tensor variables + BulletSimAPI.SetCenterOfMassByPosRot2(BSBody.ptr, ForcePosition, ForceOrientation); + }); + */ } } @@ -502,7 +511,9 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 Torque { get { return _torque; } - set { _torque = value; + set { + _torque = value; + AddAngularForce(_torque, false, false); // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); } } @@ -831,7 +842,7 @@ public sealed class BSPrim : BSPhysObject // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { - // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); + DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); BulletSimAPI.SetAngularVelocity2(BSBody.ptr, _rotationalVelocity); }); } @@ -972,14 +983,31 @@ public sealed class BSPrim : BSPhysObject } m_accumulatedAngularForces.Clear(); } - // DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); + DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) + { BulletSimAPI.ApplyTorque2(BSBody.ptr, fSum); + _torque = fSum; + } }; if (inTaintTime) addAngularForceOperation(); else - PhysicsScene.TaintedObject("BSPrim.AddForce", addAngularForceOperation); + PhysicsScene.TaintedObject("BSPrim.AddAngularForce", addAngularForceOperation); + } + // A torque impulse. + public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) + { + OMV.Vector3 applyImpulse = impulse; + BSScene.TaintCallback applyTorqueImpulseOperation = delegate() + { + DetailLog("{0},BSPrim.ApplyTorqueImpulse,taint,tImpulse={1}", LocalID, applyImpulse); + BulletSimAPI.ApplyTorqueImpulse2(BSBody.ptr, applyImpulse); + }; + if (inTaintTime) + applyTorqueImpulseOperation(); + else + PhysicsScene.TaintedObject("BSPrim.ApplyTorqueImpulse", applyTorqueImpulseOperation); } public override void SetMomentum(OMV.Vector3 momentum) { // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); @@ -1418,8 +1446,9 @@ public sealed class BSPrim : BSPhysObject PositionSanityCheck(true); - DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", - LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); + OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; + DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", + LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); // BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG -- cgit v1.1 From 364a7c308804a3e331199ca60c6dfafa406b5d0d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 31 Oct 2012 14:49:28 -0700 Subject: BulletSim: rename BSBody and BSShape to PhysBody and PhysShape. Add skeleton of BSLinksetCompound. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 78 +++++----- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 7 - .../Physics/BulletSPlugin/BSLinksetCompound.cs | 173 +++++++++++++++++++++ .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 40 ++--- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 8 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 128 +++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 20 +-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 46 +++--- 9 files changed, 328 insertions(+), 176 deletions(-) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index b9013ab..8c7061d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -131,45 +131,45 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.Destroy", LocalID); PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() { - PhysicsScene.Shapes.DereferenceBody(BSBody, true, null); - PhysicsScene.Shapes.DereferenceShape(BSShape, true, null); + PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); }); } private void SetPhysicalProperties() { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); ZeroMotion(); ForcePosition = _position; // Set the velocity and compute the proper friction ForceVelocity = _velocity; - BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution); - BulletSimAPI.SetMargin2(BSShape.ptr, PhysicsScene.Params.collisionMargin); - BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); - BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); + BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.avatarRestitution); + BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); + BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); + BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); if (PhysicsScene.Params.ccdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } UpdatePhysicalMassProperties(MassRaw); // Make so capsule does not fall over - BulletSimAPI.SetAngularFactorV2(BSBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); + BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); - BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_DEACTIVATION); - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr); + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION); + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Do this after the object has been added to the world - BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, + BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask); } @@ -199,7 +199,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { - BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); + BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); UpdatePhysicalMassProperties(MassRaw); }); @@ -234,10 +234,10 @@ public sealed class BSCharacter : BSPhysObject _rotationalVelocity = OMV.Vector3.Zero; // Zero some other properties directly into the physics engine - BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); - BulletSimAPI.ClearForces2(BSBody.ptr); + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationVelocity2(PhysBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); + BulletSimAPI.ClearForces2(PhysBody.ptr); } public override void LockAngularMotion(OMV.Vector3 axis) { return; } @@ -254,19 +254,19 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() { DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); }); } } public override OMV.Vector3 ForcePosition { get { - _position = BulletSimAPI.GetPosition2(BSBody.ptr); + _position = BulletSimAPI.GetPosition2(PhysBody.ptr); return _position; } set { _position = value; PositionSanityCheck(); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); } } @@ -313,7 +313,7 @@ public sealed class BSCharacter : BSPhysObject BSScene.TaintCallback sanityOperation = delegate() { DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); }; if (inTaintTime) sanityOperation(); @@ -332,8 +332,8 @@ public sealed class BSCharacter : BSPhysObject } public override void UpdatePhysicalMassProperties(float physMass) { - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass); - BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia); + OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); } public override OMV.Vector3 Force { @@ -344,7 +344,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() { DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); }); } } @@ -383,7 +383,7 @@ public sealed class BSCharacter : BSPhysObject if (_currentFriction != PhysicsScene.Params.avatarStandingFriction) { _currentFriction = PhysicsScene.Params.avatarStandingFriction; - BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); + BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } else @@ -391,15 +391,15 @@ public sealed class BSCharacter : BSPhysObject if (_currentFriction != PhysicsScene.Params.avatarFriction) { _currentFriction = PhysicsScene.Params.avatarFriction; - BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); + BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } _velocity = value; // Remember the set velocity so we can suppress the reduction by friction, ... _appliedVelocity = value; - BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); - BulletSimAPI.Activate2(BSBody.ptr, true); + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + BulletSimAPI.Activate2(PhysBody.ptr, true); } } public override OMV.Vector3 Torque { @@ -424,7 +424,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() { // _position = BulletSimAPI.GetPosition2(BSBody.ptr); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); }); } } @@ -433,13 +433,13 @@ public sealed class BSCharacter : BSPhysObject { get { - _orientation = BulletSimAPI.GetOrientation2(BSBody.ptr); + _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); return _orientation; } set { _orientation = value; - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); } } public override int PhysicsActorType { @@ -498,9 +498,9 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() { if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); }); } } @@ -533,7 +533,7 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); } } @@ -579,7 +579,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() { DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); }); } else @@ -647,7 +647,7 @@ public sealed class BSCharacter : BSPhysObject // That's just the way they are defined. OMV.Vector3 avVel = new OMV.Vector3(_appliedVelocity.X, _appliedVelocity.Y, entprop.Velocity.Z); _velocity = avVel; - BulletSimAPI.SetLinearVelocity2(BSBody.ptr, avVel); + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); } // Tell the linkset about value changes diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5c61774..38609e3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -514,8 +514,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (IsActive) { // Friction effects are handled by this vehicle code - BulletSimAPI.SetFriction2(Prim.BSBody.ptr, 0f); - BulletSimAPI.SetHitFraction2(Prim.BSBody.ptr, 0f); + BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); + BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 6d84fcc..525ec28 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -194,13 +194,6 @@ public abstract class BSLinkset // Called while LinkActivity is locked. protected abstract void AddChildToLinkset(BSPhysObject child); - // Forcefully removing a child from a linkset. - // This is not being called by the child so we have to make sure the child doesn't think - // it's still connected to the linkset. - // Normal OpenSimulator operation will never do this because other SceneObjectPart information - // also has to be updated (like pointer to prim's parent). - protected abstract void RemoveChildFromOtherLinkset(BSPhysObject pchild); - // I am the root of a linkset and one of my children is being removed. // Safe to call even if the child is not really in my linkset. protected abstract void RemoveChildFromLinkset(BSPhysObject child); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs new file mode 100755 index 0000000..1c569b5 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -0,0 +1,173 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSLinksetCompound : BSLinkset +{ + // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; + + public BSLinksetCompound(BSScene scene, BSPhysObject parent) + { + base.Initialize(scene, parent); + } + + // When physical properties are changed the linkset needs to recalculate + // its internal properties. + // This is queued in the 'post taint' queue so the + // refresh will happen once after all the other taints are applied. + public override void Refresh(BSPhysObject requestor) + { + // Queue to happen after all the other taint processing + PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate() + { + if (HasAnyChildren && IsRoot(requestor)) + RecomputeLinksetCompound(); + }); + } + + // The object is going dynamic (physical). Do any setup necessary + // for a dynamic linkset. + // Only the state of the passed object can be modified. The rest of the linkset + // has not yet been fully constructed. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public override bool MakeDynamic(BSPhysObject child) + { + // What is done for each object in BSPrim is what we want. + return false; + } + + // The object is going static (non-physical). Do any setup necessary for a static linkset. + // Return 'true' if any properties updated on the passed object. + // This doesn't normally happen -- OpenSim removes the objects from the physical + // world if it is a static linkset. + // Called at taint-time! + public override bool MakeStatic(BSPhysObject child) + { + // What is done for each object in BSPrim is what we want. + return false; + } + + // Called at taint-time!! + public override void UpdateProperties(BSPhysObject updated) + { + // Nothing to do for constraints on property updates + } + + // Routine called when rebuilding the body of some member of the linkset. + // Destroy all the constraints have have been made to root and set + // up to rebuild the constraints before the next simulation step. + // Returns 'true' of something was actually removed and would need restoring + // Called at taint-time!! + public override bool RemoveBodyDependencies(BSPrim child) + { + bool ret = false; + + DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); + + // Cause the current shape to be freed and the new one to be built. + Refresh(LinksetRoot); + + return ret; + } + + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. + // Called at taint-time!! + public override void RestoreBodyDependencies(BSPrim child) + { + // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. + } + + // ================================================================ + + // Add a new child to the linkset. + // Called while LinkActivity is locked. + protected override void AddChildToLinkset(BSPhysObject child) + { + if (!HasChild(child)) + { + m_children.Add(child); + + DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); + + // Cause constraints and assorted properties to be recomputed before the next simulation step. + Refresh(LinksetRoot); + } + return; + } + + // Remove the specified child from the linkset. + // Safe to call even if the child is not really in my linkset. + protected override void RemoveChildFromLinkset(BSPhysObject child) + { + if (m_children.Remove(child)) + { + DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", + child.LocalID, + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), + child.LocalID, child.PhysBody.ptr.ToString("X")); + + // See that the linkset parameters are recomputed at the end of the taint time. + Refresh(LinksetRoot); + } + else + { + // Non-fatal occurance. + // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); + } + return; + } + + + // Call each of the constraints that make up this linkset and recompute the + // various transforms and variables. Create constraints of not created yet. + // Called before the simulation step to make sure the constraint based linkset + // is all initialized. + // Called at taint time!! + private void RecomputeLinksetCompound() + { + float linksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + + // DEBUG: see of inter-linkset collisions are causing problems + // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}", + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); + + + } +} +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 8cdbd9b..65aed77 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -94,7 +94,7 @@ public sealed class BSLinksetConstraints : BSLinkset bool ret = false; DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); lock (m_linksetActivityLock) { @@ -124,9 +124,6 @@ public sealed class BSLinksetConstraints : BSLinkset { m_children.Add(child); - BSPhysObject rootx = LinksetRoot; // capture the root as of now - BSPhysObject childx = child; - DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); // Cause constraints and assorted properties to be recomputed before the next simulation step. @@ -135,17 +132,6 @@ public sealed class BSLinksetConstraints : BSLinkset return; } - // Forcefully removing a child from a linkset. - // This is not being called by the child so we have to make sure the child doesn't think - // it's still connected to the linkset. - // Normal OpenSimulator operation will never do this because other SceneObjectPart information - // also has to be updated (like pointer to prim's parent). - protected override void RemoveChildFromOtherLinkset(BSPhysObject pchild) - { - pchild.Linkset = BSLinkset.Factory(PhysicsScene, pchild); - RemoveChildFromLinkset(pchild); - } - // Remove the specified child from the linkset. // Safe to call even if the child is not really in my linkset. protected override void RemoveChildFromLinkset(BSPhysObject child) @@ -157,8 +143,8 @@ public sealed class BSLinksetConstraints : BSLinkset DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", childx.LocalID, - rootx.LocalID, rootx.BSBody.ptr.ToString("X"), - childx.LocalID, childx.BSBody.ptr.ToString("X")); + rootx.LocalID, rootx.PhysBody.ptr.ToString("X"), + childx.LocalID, childx.PhysBody.ptr.ToString("X")); PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() { @@ -197,15 +183,15 @@ public sealed class BSLinksetConstraints : BSLinkset DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, - rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), - childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), + rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), + childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"), rootPrim.Position, childPrim.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 BSConstraint6Dof constrain = new BSConstraint6Dof( - PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true ); + PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); /* NOTE: below is an attempt to build constraint with full frame computation, etc. @@ -262,14 +248,14 @@ public sealed class BSLinksetConstraints : BSLinkset bool ret = false; DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", rootPrim.LocalID, - rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), - childPrim.LocalID, childPrim.BSBody.ptr.ToString("X")); + rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), + childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X")); // Find the constraint for this link and get rid of it from the overall collection and from my list - if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody)) + if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) { // Make the child refresh its location - BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr); + BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr); ret = true; } @@ -283,7 +269,7 @@ public sealed class BSLinksetConstraints : BSLinkset { DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); - return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); + return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody); } // Call each of the constraints that make up this linkset and recompute the @@ -300,7 +286,7 @@ public sealed class BSLinksetConstraints : BSLinkset // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", - LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass); + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); foreach (BSPhysObject child in m_children) { @@ -310,7 +296,7 @@ public sealed class BSLinksetConstraints : BSLinkset child.UpdatePhysicalMassProperties(linksetMass); BSConstraint constrain; - if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) + if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) { // If constraint doesn't exist yet, create it. constrain = BuildConstraint(LinksetRoot, child); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index be8d64b..6220b21 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -68,9 +68,9 @@ public abstract class BSPhysObject : PhysicsActor public abstract void UpdatePhysicalMassProperties(float mass); // Reference to the physical body (btCollisionObject) of this object - public BulletBody BSBody; + public BulletBody PhysBody; // Reference to the physical shape (btCollisionShape) of this object - public BulletShape BSShape; + public BulletShape PhysShape; // 'true' if the mesh's underlying asset failed to build. // This will keep us from looping after the first time the build failed. @@ -206,7 +206,7 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } else @@ -220,7 +220,7 @@ public abstract class BSPhysObject : PhysicsActor SubscribedEventsMs = 0; PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } // Return 'true' if the simulator wants collision events diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 9ced61fa..8dd48ca 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -111,8 +111,8 @@ public sealed class BSPrim : BSPhysObject _mass = CalculateMass(); // No body or shape yet - BSBody = new BulletBody(LocalID, IntPtr.Zero); - BSShape = new BulletShape(IntPtr.Zero); + PhysBody = new BulletBody(LocalID, IntPtr.Zero); + PhysShape = new BulletShape(IntPtr.Zero); DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time @@ -120,7 +120,7 @@ public sealed class BSPrim : BSPhysObject { CreateGeomAndObject(true); - CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.ptr); + CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr); }); } @@ -145,8 +145,8 @@ public sealed class BSPrim : BSPhysObject { DetailLog("{0},BSPrim.Destroy,taint,", LocalID); // If there are physical body and shape, release my use of same. - PhysicsScene.Shapes.DereferenceBody(BSBody, true, null); - PhysicsScene.Shapes.DereferenceShape(BSShape, true, null); + PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); }); } @@ -243,7 +243,7 @@ public sealed class BSPrim : BSPhysObject _rotationalVelocity = OMV.Vector3.Zero; // Zero some other properties in the physics engine - BulletSimAPI.ClearAllForces2(BSBody.ptr); + BulletSimAPI.ClearAllForces2(PhysBody.ptr); } public override void LockAngularMotion(OMV.Vector3 axis) @@ -256,7 +256,7 @@ public sealed class BSPrim : BSPhysObject get { if (!Linkset.IsRoot(this)) // child prims move around based on their parent. Need to get the latest location - _position = BulletSimAPI.GetPosition2(BSBody.ptr); + _position = BulletSimAPI.GetPosition2(PhysBody.ptr); // don't do the GetObjectPosition for root elements because this function is called a zillion times // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); @@ -274,20 +274,20 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); ActivateIfPhysical(false); }); } } public override OMV.Vector3 ForcePosition { get { - _position = BulletSimAPI.GetPosition2(BSBody.ptr); + _position = BulletSimAPI.GetPosition2(PhysBody.ptr); return _position; } set { _position = value; PositionSanityCheck(); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); ActivateIfPhysical(false); } } @@ -371,15 +371,15 @@ public sealed class BSPrim : BSPhysObject { if (IsStatic) { - BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); - BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); + BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, OMV.Vector3.Zero); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); } else { - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass); - BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia); + OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); // center of mass is at the zero of the object - BulletSimAPI.SetCenterOfMassByPosRot2(BSBody.ptr, ForcePosition, ForceOrientation); + BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); // BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, localInertia); } @@ -404,7 +404,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setForce", delegate() { // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); }); } } @@ -498,7 +498,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() { // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); - BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); }); } } @@ -506,7 +506,7 @@ public sealed class BSPrim : BSPhysObject get { return _velocity; } set { _velocity = value; - BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); } } public override OMV.Vector3 Torque { @@ -531,7 +531,7 @@ public sealed class BSPrim : BSPhysObject if (!Linkset.IsRoot(this)) { // Children move around because tied to parent. Get a fresh value. - _orientation = BulletSimAPI.GetOrientation2(BSBody.ptr); + _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); } return _orientation; } @@ -544,7 +544,7 @@ public sealed class BSPrim : BSPhysObject { // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); }); } } @@ -553,13 +553,13 @@ public sealed class BSPrim : BSPhysObject { get { - _orientation = BulletSimAPI.GetOrientation2(BSBody.ptr); + _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); return _orientation; } set { _orientation = value; - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); } } public override int PhysicsActorType { @@ -615,7 +615,7 @@ public sealed class BSPrim : BSPhysObject // Mangling all the physical properties requires the object not be in the physical world. // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); // Set up the object physicalness (does gravity and collisions move this object) MakeDynamic(IsStatic); @@ -629,15 +629,15 @@ public sealed class BSPrim : BSPhysObject // Make solid or not (do things bounce off or pass through this object). MakeSolid(IsSolid); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); // Rebuild its shape - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr); + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Collision filter can be set only when the object is in the world - if (BSBody.collisionFilter != 0 || BSBody.collisionMask != 0) + if (PhysBody.collisionFilter != 0 || PhysBody.collisionMask != 0) { - BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, (uint)BSBody.collisionFilter, (uint)BSBody.collisionMask); + BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, (uint)PhysBody.collisionFilter, (uint)PhysBody.collisionMask); } // Recompute any linkset parameters. @@ -646,7 +646,7 @@ public sealed class BSPrim : BSPhysObject Linkset.Refresh(this); DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", - LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); + LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); } // "Making dynamic" means changing to and from static. @@ -659,44 +659,44 @@ public sealed class BSPrim : BSPhysObject if (makeStatic) { // Become a Bullet 'static' object type - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement ZeroMotion(); // Center of mass is at the center of the object - BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation); + BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f); // Set collision detection parameters if (PhysicsScene.Params.ccdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } // There can be special things needed for implementing linksets Linkset.MakeStatic(this); // The activation state is 'disabled' so Bullet will not try to act on it. - BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION); + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); // Start it out sleeping and physical actions could wake it up. // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); - BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; - BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask; + PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; + PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; } else { // Not a Bullet static object - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Set various physical properties so internal dynamic properties will get computed correctly as they are set - BulletSimAPI.SetFriction2(BSBody.ptr, PhysicsScene.Params.defaultFriction); - BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.defaultRestitution); + BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); + BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 // Since this can be called multiple times, only zero forces when becoming physical // BulletSimAPI.ClearAllForces2(BSBody.ptr); // For good measure, make sure the transform is set through to the motion state - BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); // A dynamic object has mass UpdatePhysicalMassProperties(MassRaw); @@ -704,26 +704,26 @@ public sealed class BSPrim : BSPhysObject // Set collision detection parameters if (PhysicsScene.Params.ccdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } // Various values for simulation limits - BulletSimAPI.SetDamping2(BSBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); - BulletSimAPI.SetDeactivationTime2(BSBody.ptr, PhysicsScene.Params.deactivationTime); - BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); - BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); + BulletSimAPI.SetDamping2(PhysBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); + BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, PhysicsScene.Params.deactivationTime); + BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); + BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); // There might be special things needed for implementing linksets. Linkset.MakeDynamic(this); // Force activation of the object so Bullet will act on it. // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. - BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); // BulletSimAPI.Activate2(BSBody.ptr, true); - BSBody.collisionFilter = CollisionFilterGroups.ObjectFilter; - BSBody.collisionMask = CollisionFilterGroups.ObjectMask; + PhysBody.collisionFilter = CollisionFilterGroups.ObjectFilter; + PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; } } @@ -733,7 +733,7 @@ public sealed class BSPrim : BSPhysObject // the functions after this one set up the state of a possibly newly created collision body. private void MakeSolid(bool makeSolid) { - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr); + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr); if (makeSolid) { // Verify the previous code created the correct shape for this type of thing. @@ -741,7 +741,7 @@ public sealed class BSPrim : BSPhysObject { m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); } - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); } else { @@ -749,9 +749,9 @@ public sealed class BSPrim : BSPhysObject { m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); } - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - BSBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; - BSBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + PhysBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; + PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; } } @@ -761,7 +761,7 @@ public sealed class BSPrim : BSPhysObject private void ActivateIfPhysical(bool forceIt) { if (IsPhysical) - BulletSimAPI.Activate2(BSBody.ptr, forceIt); + BulletSimAPI.Activate2(PhysBody.ptr, forceIt); } // Turn on or off the flag controlling whether collision events are returned to the simulator. @@ -769,11 +769,11 @@ public sealed class BSPrim : BSPhysObject { if (wantsCollisionEvents) { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } else { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } } @@ -818,9 +818,9 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() { if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); }); } } @@ -843,7 +843,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - BulletSimAPI.SetAngularVelocity2(BSBody.ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); }); } } @@ -853,7 +853,7 @@ public sealed class BSPrim : BSPhysObject } set { _rotationalVelocity = value; - BulletSimAPI.SetAngularVelocity2(BSBody.ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); } } public override bool Kinematic { @@ -879,7 +879,7 @@ public sealed class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); } } @@ -946,7 +946,7 @@ public sealed class BSPrim : BSPhysObject } DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) - BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); }; if (inTaintTime) addForceOperation(); @@ -986,7 +986,7 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) { - BulletSimAPI.ApplyTorque2(BSBody.ptr, fSum); + BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); _torque = fSum; } }; @@ -1002,7 +1002,7 @@ public sealed class BSPrim : BSPhysObject BSScene.TaintCallback applyTorqueImpulseOperation = delegate() { DetailLog("{0},BSPrim.ApplyTorqueImpulse,taint,tImpulse={1}", LocalID, applyImpulse); - BulletSimAPI.ApplyTorqueImpulse2(BSBody.ptr, applyImpulse); + BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); }; if (inTaintTime) applyTorqueImpulseOperation(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index c27b5f0..cc5dbb2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1067,49 +1067,49 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linearDamping; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.BSBody.ptr, v, v); } ), + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, v); } ), new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 0f, (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].angularDamping; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.BSBody.ptr, v, v); } ), + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, v); } ), new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 0.2f, (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].deactivationTime; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.BSBody.ptr, v); } ), + (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 0.8f, (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linearSleepingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.BSBody.ptr, v, v); } ), + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1.0f, (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].angularSleepingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.BSBody.ptr, v, v); } ), + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 0f, // set to zero to disable (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdMotionThreshold; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.BSBody.ptr, v); } ), + (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 0f, (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdSweptSphereRadius; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.BSBody.ptr, v); } ), + (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 0.1f, (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].contactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.BSBody.ptr, v); } ), + (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 0.5f, @@ -1428,8 +1428,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { foreach (BSPrim prim in m_vehicles) { - BulletSimAPI.DumpRigidBody2(World.ptr, prim.BSBody.ptr); - BulletSimAPI.DumpCollisionShape2(World.ptr, prim.BSShape.ptr); + BulletSimAPI.DumpRigidBody2(World.ptr, prim.PhysBody.ptr); + BulletSimAPI.DumpCollisionShape2(World.ptr, prim.PhysShape.ptr); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 1219fc0..a38e650 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -106,11 +106,11 @@ public sealed class BSShapeCollection : IDisposable // rebuild the body around it. // Updates prim.BSBody with information/pointers to requested body bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, - prim.BSShape, shapeData, bodyCallback); + prim.PhysShape, shapeData, bodyCallback); ret = newGeom || newBody; } DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", - prim.LocalID, forceRebuild, ret, prim.BSBody, prim.BSShape); + prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape); return ret; } @@ -337,7 +337,7 @@ public sealed class BSShapeCollection : IDisposable // an avatar capsule is close to a native shape (it is not shared) ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR, ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.BSShape); + DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; haveShape = true; } @@ -360,13 +360,13 @@ public sealed class BSShapeCollection : IDisposable haveShape = true; if (forceRebuild || prim.Scale != shapeData.Size - || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE + || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE ) { ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", - prim.LocalID, forceRebuild, prim.BSShape); + prim.LocalID, forceRebuild, prim.PhysShape); } } if (pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) @@ -374,13 +374,13 @@ public sealed class BSShapeCollection : IDisposable haveShape = true; if (forceRebuild || prim.Scale != shapeData.Size - || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX + || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX ) { ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", - prim.LocalID, forceRebuild, prim.BSShape); + prim.LocalID, forceRebuild, prim.PhysShape); } } } @@ -394,13 +394,13 @@ public sealed class BSShapeCollection : IDisposable // Update prim.BSShape to reference a hull of this shape. ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", - shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); + shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } else { ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", - shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); + shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } } return ret; @@ -413,7 +413,7 @@ public sealed class BSShapeCollection : IDisposable ShapeDestructionCallback shapeCallback) { // release any previous shape - DereferenceShape(prim.BSShape, true, shapeCallback); + DereferenceShape(prim.PhysShape, true, shapeCallback); shapeData.Type = shapeType; // Bullet native objects are scaled by the Bullet engine so pass the size in @@ -426,7 +426,7 @@ public sealed class BSShapeCollection : IDisposable DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", shapeData.ID, newShape, shapeData.Scale); - prim.BSShape = newShape; + prim.PhysShape = newShape; return true; } @@ -475,14 +475,14 @@ public sealed class BSShapeCollection : IDisposable System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); // if this new shape is the same as last time, don't recreate the mesh - if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) + if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) return false; DetailLog("{0},BSShapeCollection.CreateGeomMesh,create,oldKey={1},newKey={2}", - prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); + prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); // Since we're recreating new, get rid of the reference to the previous shape - DereferenceShape(prim.BSShape, true, shapeCallback); + DereferenceShape(prim.PhysShape, true, shapeCallback); newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod); // Take evasive action if the mesh was not constructed. @@ -492,7 +492,7 @@ public sealed class BSShapeCollection : IDisposable // meshes are already scaled by the meshmerizer prim.Scale = new OMV.Vector3(1f, 1f, 1f); - prim.BSShape = newShape; + prim.PhysShape = newShape; return true; // 'true' means a new shape has been added to this prim } @@ -550,14 +550,14 @@ public sealed class BSShapeCollection : IDisposable System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod); // if the hull hasn't changed, don't rebuild it - if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) + if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) return false; DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", - prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); + prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); // Remove usage of the previous shape. - DereferenceShape(prim.BSShape, true, shapeCallback); + DereferenceShape(prim.PhysShape, true, shapeCallback); newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs); @@ -566,7 +566,7 @@ public sealed class BSShapeCollection : IDisposable // hulls are already scaled by the meshmerizer prim.Scale = new OMV.Vector3(1f, 1f, 1f); - prim.BSShape = newShape; + prim.PhysShape = newShape; return true; // 'true' means a new shape has been added to this prim } @@ -778,13 +778,13 @@ public sealed class BSShapeCollection : IDisposable bool ret = false; // the mesh, hull or native shape must have already been created in Bullet - bool mustRebuild = (prim.BSBody.ptr == IntPtr.Zero); + bool mustRebuild = (prim.PhysBody.ptr == IntPtr.Zero); // If there is an existing body, verify it's of an acceptable type. // If not a solid object, body is a GhostObject. Otherwise a RigidBody. if (!mustRebuild) { - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.BSBody.ptr); + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr); if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) { @@ -796,7 +796,7 @@ public sealed class BSShapeCollection : IDisposable if (mustRebuild || forceRebuild) { // Free any old body - DereferenceBody(prim.BSBody, true, bodyCallback); + DereferenceBody(prim.PhysBody, true, bodyCallback); BulletBody aBody; IntPtr bodyPtr = IntPtr.Zero; @@ -816,7 +816,7 @@ public sealed class BSShapeCollection : IDisposable ReferenceBody(aBody, true); - prim.BSBody = aBody; + prim.PhysBody = aBody; ret = true; } -- cgit v1.1 From 39c02dcc8c537d5989238ec97c876e033895a8a9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 1 Nov 2012 10:23:37 -0700 Subject: BulletSim: Remove use of shapeData in ShapeCollection and rely on the available BSPhysObject varaiables. Fix line endings in BSLinksetCompound. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 19 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 5 + .../Physics/BulletSPlugin/BSLinksetCompound.cs | 347 +++++++++++---------- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 + OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 30 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 116 +++---- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 1 + 7 files changed, 256 insertions(+), 266 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8c7061d..2a634b9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -99,26 +99,12 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw); - ShapeData shapeData = new ShapeData(); - shapeData.ID = LocalID; - shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; - shapeData.Position = _position; - shapeData.Rotation = _orientation; - shapeData.Velocity = _velocity; - shapeData.Size = Scale; // capsule is a native shape but scale is not just <1,1,1> - shapeData.Scale = Scale; - shapeData.Mass = _mass; - shapeData.Buoyancy = _buoyancy; - shapeData.Static = ShapeData.numericFalse; - shapeData.Friction = PhysicsScene.Params.avatarStandingFriction; - shapeData.Restitution = PhysicsScene.Params.avatarRestitution; - // do actual create at taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into BSBody and BSShape - PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null); + PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, null, null); SetPhysicalProperties(); }); @@ -212,6 +198,9 @@ public sealed class BSCharacter : BSPhysObject { set { BaseShape = value; } } + // I want the physics engine to make an avatar capsule + public override ShapeData.PhysicsShapeType PreferredPhysicalShape + { get { return ShapeData.PhysicsShapeType.SHAPE_AVATAR; } } public override bool Grabbed { set { _grabbed = value; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 525ec28..f56851f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -68,6 +68,11 @@ public abstract class BSLinkset // to the physical representation is done via the tainting mechenism. protected object m_linksetActivityLock = new Object(); + // Some linksets have a preferred physical shape. + // Returns SHAPE_UNKNOWN if there is no preference. + public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape + { get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } } + // We keep the prim's mass in the linkset structure since it could be dependent on other prims protected float m_mass; public float LinksetMass diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 1c569b5..638fae1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -1,173 +1,176 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OMV = OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -public sealed class BSLinksetCompound : BSLinkset -{ - // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; - - public BSLinksetCompound(BSScene scene, BSPhysObject parent) - { - base.Initialize(scene, parent); - } - - // When physical properties are changed the linkset needs to recalculate - // its internal properties. - // This is queued in the 'post taint' queue so the - // refresh will happen once after all the other taints are applied. - public override void Refresh(BSPhysObject requestor) - { - // Queue to happen after all the other taint processing - PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate() - { - if (HasAnyChildren && IsRoot(requestor)) - RecomputeLinksetCompound(); - }); - } - - // The object is going dynamic (physical). Do any setup necessary - // for a dynamic linkset. - // Only the state of the passed object can be modified. The rest of the linkset - // has not yet been fully constructed. - // Return 'true' if any properties updated on the passed object. - // Called at taint-time! - public override bool MakeDynamic(BSPhysObject child) - { - // What is done for each object in BSPrim is what we want. - return false; - } - - // The object is going static (non-physical). Do any setup necessary for a static linkset. - // Return 'true' if any properties updated on the passed object. - // This doesn't normally happen -- OpenSim removes the objects from the physical - // world if it is a static linkset. - // Called at taint-time! - public override bool MakeStatic(BSPhysObject child) - { - // What is done for each object in BSPrim is what we want. - return false; - } - - // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated) - { - // Nothing to do for constraints on property updates - } - - // Routine called when rebuilding the body of some member of the linkset. - // Destroy all the constraints have have been made to root and set - // up to rebuild the constraints before the next simulation step. - // Returns 'true' of something was actually removed and would need restoring - // Called at taint-time!! - public override bool RemoveBodyDependencies(BSPrim child) - { - bool ret = false; - - DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); - - // Cause the current shape to be freed and the new one to be built. - Refresh(LinksetRoot); - - return ret; - } - - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public override void RestoreBodyDependencies(BSPrim child) - { - // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. - } - - // ================================================================ - - // Add a new child to the linkset. - // Called while LinkActivity is locked. - protected override void AddChildToLinkset(BSPhysObject child) - { - if (!HasChild(child)) - { - m_children.Add(child); - - DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); - - // Cause constraints and assorted properties to be recomputed before the next simulation step. - Refresh(LinksetRoot); - } - return; - } - - // Remove the specified child from the linkset. - // Safe to call even if the child is not really in my linkset. - protected override void RemoveChildFromLinkset(BSPhysObject child) - { - if (m_children.Remove(child)) - { - DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", - child.LocalID, - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), - child.LocalID, child.PhysBody.ptr.ToString("X")); - - // See that the linkset parameters are recomputed at the end of the taint time. - Refresh(LinksetRoot); - } - else - { - // Non-fatal occurance. - // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); - } - return; - } - - - // Call each of the constraints that make up this linkset and recompute the - // various transforms and variables. Create constraints of not created yet. - // Called before the simulation step to make sure the constraint based linkset - // is all initialized. - // Called at taint time!! - private void RecomputeLinksetCompound() - { - float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); - - // DEBUG: see of inter-linkset collisions are causing problems - // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}", - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); - - - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSLinksetCompound : BSLinkset +{ + // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; + + public BSLinksetCompound(BSScene scene, BSPhysObject parent) + { + base.Initialize(scene, parent); + } + + // When physical properties are changed the linkset needs to recalculate + // its internal properties. + // This is queued in the 'post taint' queue so the + // refresh will happen once after all the other taints are applied. + public override void Refresh(BSPhysObject requestor) + { + // Queue to happen after all the other taint processing + PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate() + { + if (HasAnyChildren && IsRoot(requestor)) + RecomputeLinksetCompound(); + }); + } + + // The object is going dynamic (physical). Do any setup necessary + // for a dynamic linkset. + // Only the state of the passed object can be modified. The rest of the linkset + // has not yet been fully constructed. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public override bool MakeDynamic(BSPhysObject child) + { + // What is done for each object in BSPrim is what we want. + return false; + } + + // The object is going static (non-physical). Do any setup necessary for a static linkset. + // Return 'true' if any properties updated on the passed object. + // This doesn't normally happen -- OpenSim removes the objects from the physical + // world if it is a static linkset. + // Called at taint-time! + public override bool MakeStatic(BSPhysObject child) + { + // What is done for each object in BSPrim is what we want. + return false; + } + + // Called at taint-time!! + public override void UpdateProperties(BSPhysObject updated) + { + // Nothing to do for constraints on property updates + } + + // Routine called when rebuilding the body of some member of the linkset. + // Destroy all the constraints have have been made to root and set + // up to rebuild the constraints before the next simulation step. + // Returns 'true' of something was actually removed and would need restoring + // Called at taint-time!! + public override bool RemoveBodyDependencies(BSPrim child) + { + bool ret = false; + + DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); + + // Cause the current shape to be freed and the new one to be built. + Refresh(LinksetRoot); + + return ret; + } + + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. + // Called at taint-time!! + public override void RestoreBodyDependencies(BSPrim child) + { + // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. + } + + // ================================================================ + + // Add a new child to the linkset. + // Called while LinkActivity is locked. + protected override void AddChildToLinkset(BSPhysObject child) + { + if (!HasChild(child)) + { + m_children.Add(child); + + DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); + + // Cause constraints and assorted properties to be recomputed before the next simulation step. + Refresh(LinksetRoot); + } + return; + } + + // Remove the specified child from the linkset. + // Safe to call even if the child is not really in my linkset. + protected override void RemoveChildFromLinkset(BSPhysObject child) + { + if (m_children.Remove(child)) + { + DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", + child.LocalID, + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), + child.LocalID, child.PhysBody.ptr.ToString("X")); + + // See that the linkset parameters are recomputed at the end of the taint time. + Refresh(LinksetRoot); + } + else + { + // Non-fatal occurance. + // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); + } + return; + } + + + // Call each of the constraints that make up this linkset and recompute the + // various transforms and variables. Create constraints of not created yet. + // Called before the simulation step to make sure the constraint based linkset + // is all initialized. + // Called at taint time!! + private void RecomputeLinksetCompound() + { + // Release the existing shape + PhysicsScene.Shapes.DereferenceShape(LinksetRoot.PhysShape, true, null); + + float linksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + + // DEBUG: see of inter-linkset collisions are causing problems + // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}", + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); + + + } +} } \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 6220b21..7d91468 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor // The objects base shape information. Null if not a prim type shape. public PrimitiveBaseShape BaseShape { get; protected set; } + // Some types of objects have preferred physical representations. + // Returns SHAPE_UNKNOWN if there is no preference. + public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape + { get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } } // When the physical properties are updated, an EntityProperty holds the update values. // Keep the current and last EntityProperties to enable computation of differences diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8dd48ca..8ce960d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -171,6 +171,10 @@ public sealed class BSPrim : BSPhysObject ForceBodyShapeRebuild(false); } } + // Whatever the linkset wants is what I want. + public override ShapeData.PhysicsShapeType PreferredPhysicalShape + { get { return Linkset.PreferredPhysicalShape; } } + public override bool ForceBodyShapeRebuild(bool inTaintTime) { LastAssetBuildFailed = false; @@ -1310,34 +1314,11 @@ public sealed class BSPrim : BSPhysObject }// end CalculateMass #endregion Mass Calculation - // Copy prim's info into the BulletSim shape description structure - public void FillShapeInfo(out ShapeData shape) - { - shape.ID = LocalID; - shape.Type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; - shape.Position = _position; - shape.Rotation = _orientation; - shape.Velocity = _velocity; - shape.Size = _size; - shape.Scale = Scale; - shape.Mass = _isPhysical ? _mass : 0f; - shape.Buoyancy = _buoyancy; - shape.HullKey = 0; - shape.MeshKey = 0; - shape.Friction = _friction; - shape.Restitution = _restitution; - shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; - shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; - shape.Solid = IsSolid ? ShapeData.numericFalse : ShapeData.numericTrue; - } // Rebuild the geometry and object. // This is called when the shape changes so we need to recreate the mesh/hull. // Called at taint-time!!! private void CreateGeomAndObject(bool forceRebuild) { - ShapeData shapeData; - FillShapeInfo(out shapeData); - // If this prim is part of a linkset, we must remove and restore the physical // links if the body is rebuilt. bool needToRestoreLinkset = false; @@ -1346,8 +1327,7 @@ public sealed class BSPrim : BSPhysObject // Updates BSBody and BSShape with the new information. // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. // Returns 'true' if either the body or the shape was changed. - PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, shapeData, BaseShape, - null, delegate(BulletBody dBody) + PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) { // Called if the current prim body is about to be destroyed. // Remove all the physical dependencies on the old body. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index a38e650..478924a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -90,7 +90,6 @@ public sealed class BSShapeCollection : IDisposable // remove the physical constraints before the body is destroyed. // Called at taint-time!! public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, - ShapeData shapeData, PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) { bool ret = false; @@ -101,12 +100,12 @@ public sealed class BSShapeCollection : IDisposable // Do we have the correct geometry for this type of object? // Updates prim.BSShape with information/pointers to shape. // CreateGeom returns 'true' of BSShape as changed to a new shape. - bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback); + bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback); // If we had to select a new shape geometry for the object, // rebuild the body around it. // Updates prim.BSBody with information/pointers to requested body bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, - prim.PhysShape, shapeData, bodyCallback); + prim.PhysShape, bodyCallback); ret = newGeom || newBody; } DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", @@ -261,6 +260,9 @@ public sealed class BSShapeCollection : IDisposable case ShapeData.PhysicsShapeType.SHAPE_MESH: DereferenceMesh(shape, shapeCallback); break; + case ShapeData.PhysicsShapeType.SHAPE_COMPOUND: + DereferenceCompound(shape, shapeCallback); + break; case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: break; default: @@ -317,6 +319,13 @@ public sealed class BSShapeCollection : IDisposable } } + // Remove a reference to a compound shape. + // Called at taint-time. + private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) + { + // Compound shape is made of a bunch of meshes and natives. + } + // Create the geometry information in Bullet for later use. // The objects needs a hull if it's physical otherwise a mesh is enough. // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls, @@ -325,17 +334,17 @@ public sealed class BSShapeCollection : IDisposable // Info in prim.BSShape is updated to the new shape. // Returns 'true' if the geometry was rebuilt. // Called at taint-time! - private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeData shapeData, - PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback) + private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; bool haveShape = false; bool nativeShapePossible = true; + PrimitiveBaseShape pbs = prim.BaseShape; - if (shapeData.Type == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) { // an avatar capsule is close to a native shape (it is not shared) - ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR, + ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; @@ -359,11 +368,11 @@ public sealed class BSShapeCollection : IDisposable { haveShape = true; if (forceRebuild - || prim.Scale != shapeData.Size + || prim.Scale != prim.Size || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE ) { - ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, + ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); @@ -373,11 +382,11 @@ public sealed class BSShapeCollection : IDisposable { haveShape = true; if (forceRebuild - || prim.Scale != shapeData.Size + || prim.Scale != prim.Size || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX ) { - ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, + ret = GetReferenceToNativeShape( prim, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); @@ -392,15 +401,15 @@ public sealed class BSShapeCollection : IDisposable if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) { // Update prim.BSShape to reference a hull of this shape. - ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); + ret = GetReferenceToHull(prim,shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", - shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); + prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } else { - ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback); + ret = GetReferenceToMesh(prim, shapeCallback); DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", - shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); + prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } } return ret; @@ -408,44 +417,45 @@ public sealed class BSShapeCollection : IDisposable // Creates a native shape and assignes it to prim.BSShape. // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). - private bool GetReferenceToNativeShape(BSPhysObject prim, ShapeData shapeData, + private bool GetReferenceToNativeShape(BSPhysObject prim, ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, ShapeDestructionCallback shapeCallback) { // release any previous shape DereferenceShape(prim.PhysShape, true, shapeCallback); - shapeData.Type = shapeType; // Bullet native objects are scaled by the Bullet engine so pass the size in - prim.Scale = shapeData.Size; - shapeData.Scale = shapeData.Size; + prim.Scale = prim.Size; - BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey); + BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", - shapeData.ID, newShape, shapeData.Scale); + prim.LocalID, newShape, prim.Scale); prim.PhysShape = newShape; return true; } - private BulletShape BuildPhysicalNativeShape(ShapeData.PhysicsShapeType shapeType, - ShapeData shapeData, ShapeData.FixedShapeKey shapeKey) + private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, ShapeData.PhysicsShapeType shapeType, + ShapeData.FixedShapeKey shapeKey) { BulletShape newShape; // Need to make sure the passed shape information is for the native type. - ShapeData nativeShapeData = shapeData; + ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; + nativeShapeData.ID = prim.LocalID; + nativeShapeData.Scale = prim.Scale; + nativeShapeData.Size = prim.Scale; nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) { newShape = new BulletShape( - BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, nativeShapeData.Scale) + BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) , shapeType); - DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale); + DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { @@ -454,7 +464,7 @@ public sealed class BSShapeCollection : IDisposable if (newShape.ptr == IntPtr.Zero) { PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", - LogHeader, nativeShapeData.ID, nativeShapeData.Type); + LogHeader, prim.LocalID, shapeType); } newShape.shapeKey = (System.UInt64)shapeKey; newShape.isNativeShape = true; @@ -466,13 +476,12 @@ public sealed class BSShapeCollection : IDisposable // Dereferences previous shape in BSShape and adds a reference for this new shape. // Returns 'true' of a mesh was actually built. Otherwise . // Called at taint-time! - private bool GetReferenceToMesh(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs, - ShapeDestructionCallback shapeCallback) + private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { BulletShape newShape = new BulletShape(IntPtr.Zero); float lod; - System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); + System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); // if this new shape is the same as last time, don't recreate the mesh if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) @@ -484,9 +493,9 @@ public sealed class BSShapeCollection : IDisposable // Since we're recreating new, get rid of the reference to the previous shape DereferenceShape(prim.PhysShape, true, shapeCallback); - newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod); + newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod); // Take evasive action if the mesh was not constructed. - newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs); + newShape = VerifyMeshCreated(newShape, prim); ReferenceShape(newShape); @@ -541,13 +550,12 @@ public sealed class BSShapeCollection : IDisposable // See that hull shape exists in the physical world and update prim.BSShape. // We could be creating the hull because scale changed or whatever. - private bool GetReferenceToHull(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs, - ShapeDestructionCallback shapeCallback) + private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { BulletShape newShape; float lod; - System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod); + System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); // if the hull hasn't changed, don't rebuild it if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) @@ -559,8 +567,8 @@ public sealed class BSShapeCollection : IDisposable // Remove usage of the previous shape. DereferenceShape(prim.PhysShape, true, shapeCallback); - newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); - newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs); + newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); + newShape = VerifyMeshCreated(newShape, prim); ReferenceShape(newShape); @@ -687,7 +695,7 @@ public sealed class BSShapeCollection : IDisposable // Create a hash of all the shape parameters to be used as a key // for this particular shape. - private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) + private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) { // level of detail based on size and type of the object float lod = PhysicsScene.MeshLOD; @@ -695,40 +703,40 @@ public sealed class BSShapeCollection : IDisposable lod = PhysicsScene.SculptLOD; // Mega prims usually get more detail because one can interact with shape approximations at this size. - float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); + float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) lod = PhysicsScene.MeshMegaPrimLOD; retLod = lod; - return pbs.GetMeshKey(shapeData.Size, lod); + return pbs.GetMeshKey(size, lod); } // For those who don't want the LOD - private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) + private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs) { float lod; - return ComputeShapeKey(shapeData, pbs, out lod); + return ComputeShapeKey(size, pbs, out lod); } // The creation of a mesh or hull can fail if an underlying asset is not available. // There are two cases: 1) the asset is not in the cache and it needs to be fetched; - // and 2) the asset cannot be converted (like decompressing JPEG2000s). - // The first case causes the asset to be fetched. The second case just requires + // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). + // The first case causes the asset to be fetched. The second case requires // us to not loop forever. // Called after creating a physical mesh or hull. If the physical shape was created, // just return. - private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs) + private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) { // If the shape was successfully created, nothing more to do if (newShape.ptr != IntPtr.Zero) return newShape; // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset - if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero) + if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) { prim.LastAssetBuildFailed = true; BSPhysObject xprim = prim; DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", - LogHeader, shapeData.ID.ToString("X"), prim.LastAssetBuildFailed); + LogHeader, prim.LocalID, prim.LastAssetBuildFailed); Util.FireAndForget(delegate { RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; @@ -745,7 +753,7 @@ public sealed class BSShapeCollection : IDisposable yprim.BaseShape.SculptData = asset.Data; // This will cause the prim to see that the filler shape is not the right // one and try again to build the object. - // No race condition with the native sphere setting since the rebuild is at taint time. + // No race condition with the normal shape setting since the rebuild is at taint time. yprim.ForceBodyShapeRebuild(false); }); @@ -757,13 +765,13 @@ public sealed class BSShapeCollection : IDisposable if (prim.LastAssetBuildFailed) { PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", - LogHeader, shapeData.ID, pbs.SculptTexture); + LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); } } // While we figure out the real problem, stick a simple native shape on the object. BulletShape fillinShape = - BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_BOX, shapeData, ShapeData.FixedShapeKey.KEY_BOX); + BuildPhysicalNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); return fillinShape; } @@ -773,7 +781,7 @@ public sealed class BSShapeCollection : IDisposable // Returns 'true' if an object was actually created. // Called at taint-time. private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, - ShapeData shapeData, BodyDestructionCallback bodyCallback) + BodyDestructionCallback bodyCallback) { bool ret = false; @@ -803,16 +811,16 @@ public sealed class BSShapeCollection : IDisposable if (prim.IsSolid) { bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, - shapeData.ID, shapeData.Position, shapeData.Rotation); + prim.LocalID, prim.ForcePosition, prim.ForceOrientation); DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } else { bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, - shapeData.ID, shapeData.Position, shapeData.Rotation); + prim.LocalID, prim.ForcePosition, prim.ForceOrientation); DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } - aBody = new BulletBody(shapeData.ID, bodyPtr); + aBody = new BulletBody(prim.LocalID, bodyPtr); ReferenceBody(aBody, true); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 9b7ba03..3b6355c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -194,6 +194,7 @@ public struct ShapeData // following defined by BulletSim SHAPE_GROUNDPLANE = 20, SHAPE_TERRAIN = 21, + SHAPE_COMPOUND = 22, }; public uint ID; public PhysicsShapeType Type; -- cgit v1.1 From f53b4e7a21f62a84e237c4ce8d2806124c3a76d2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 1 Nov 2012 10:53:55 -0700 Subject: BulletSim: Add RawPosition and RawOrientation to BSPhysObject and rename MassRaw to RawMass. Fix BSShapeCollection to use Raw* for creating the body to eliminate exception from referencing the physical body before it has been created. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 20 +++++++++++++++----- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 16 ++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 +++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 14 ++++++++++++-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 2a634b9..9e1206a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -97,7 +97,7 @@ public sealed class BSCharacter : BSPhysObject // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", - LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw); + LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); // do actual create at taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() @@ -141,7 +141,7 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } - UpdatePhysicalMassProperties(MassRaw); + UpdatePhysicalMassProperties(RawMass); // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); @@ -181,12 +181,12 @@ public sealed class BSCharacter : BSPhysObject ComputeAvatarScale(_size); ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.setSize,call,scale={1},density={2},volume={3},mass={4}", - LocalID, Scale, _avatarDensity, _avatarVolume, MassRaw); + LocalID, Scale, _avatarDensity, _avatarVolume, RawMass); PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - UpdatePhysicalMassProperties(MassRaw); + UpdatePhysicalMassProperties(RawMass); }); } @@ -231,6 +231,11 @@ public sealed class BSCharacter : BSPhysObject public override void LockAngularMotion(OMV.Vector3 axis) { return; } + public override OMV.Vector3 RawPosition + { + get { return _position; } + set { _position = value; } + } public override OMV.Vector3 Position { get { // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID); @@ -316,7 +321,7 @@ public sealed class BSCharacter : BSPhysObject public override float Mass { get { return _mass; } } // used when we only want this prim's mass and not the linkset thing - public override float MassRaw { + public override float RawMass { get {return _mass; } } public override void UpdatePhysicalMassProperties(float physMass) @@ -405,6 +410,11 @@ public sealed class BSCharacter : BSPhysObject get { return _acceleration; } set { _acceleration = value; } } + public override OMV.Quaternion RawOrientation + { + get { return _orientation; } + set { _orientation = value; } + } public override OMV.Quaternion Orientation { get { return _orientation; } set { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index f56851f..9e0f499 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -106,7 +106,7 @@ public abstract class BSLinkset PhysicsScene = scene; LinksetRoot = parent; m_children = new HashSet(); - m_mass = parent.MassRaw; + m_mass = parent.RawMass; } // Link to a linkset where the child knows the parent. @@ -242,14 +242,14 @@ public abstract class BSLinkset // ================================================================ protected virtual float ComputeLinksetMass() { - float mass = LinksetRoot.MassRaw; + float mass = LinksetRoot.RawMass; if (HasAnyChildren) { lock (m_linksetActivityLock) { foreach (BSPhysObject bp in m_children) { - mass += bp.MassRaw; + mass += bp.RawMass; } } } @@ -261,13 +261,13 @@ public abstract class BSLinkset OMV.Vector3 com; lock (m_linksetActivityLock) { - com = LinksetRoot.Position * LinksetRoot.MassRaw; - float totalMass = LinksetRoot.MassRaw; + com = LinksetRoot.Position * LinksetRoot.RawMass; + float totalMass = LinksetRoot.RawMass; foreach (BSPhysObject bp in m_children) { - com += bp.Position * bp.MassRaw; - totalMass += bp.MassRaw; + com += bp.Position * bp.RawMass; + totalMass += bp.RawMass; } if (totalMass != 0f) com /= totalMass; @@ -285,7 +285,7 @@ public abstract class BSLinkset foreach (BSPhysObject bp in m_children) { - com += bp.Position * bp.MassRaw; + com += bp.Position * bp.RawMass; } com /= (m_children.Count + 1); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 7d91468..65d7f34 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -63,7 +63,7 @@ public abstract class BSPhysObject : PhysicsActor public BSLinkset Linkset { get; set; } // Return the object mass without calculating it or having side effects - public abstract float MassRaw { get; } + public abstract float RawMass { get; } // Set the raw mass but also update physical mass properties (inertia, ...) public abstract void UpdatePhysicalMassProperties(float mass); @@ -105,8 +105,10 @@ public abstract class BSPhysObject : PhysicsActor // Tell the object to clean up. public abstract void Destroy(); + public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } + public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } public abstract OMV.Vector3 ForceVelocity { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8ce960d..1754be6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -256,6 +256,11 @@ public sealed class BSPrim : BSPhysObject return; } + public override OMV.Vector3 RawPosition + { + get { return _position; } + set { _position = value; } + } public override OMV.Vector3 Position { get { if (!Linkset.IsRoot(this)) @@ -366,7 +371,7 @@ public sealed class BSPrim : BSPhysObject } // used when we only want this prim's mass and not the linkset thing - public override float MassRaw { + public override float RawMass { get { return _mass; } } // Set the physical mass to the passed mass. @@ -530,6 +535,11 @@ public sealed class BSPrim : BSPhysObject get { return _acceleration; } set { _acceleration = value; } } + public override OMV.Quaternion RawOrientation + { + get { return _orientation; } + set { _orientation = value; } + } public override OMV.Quaternion Orientation { get { if (!Linkset.IsRoot(this)) @@ -703,7 +713,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); // A dynamic object has mass - UpdatePhysicalMassProperties(MassRaw); + UpdatePhysicalMassProperties(RawMass); // Set collision detection parameters if (PhysicsScene.Params.ccdMotionThreshold > 0f) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 478924a..e131919 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -811,7 +811,7 @@ public sealed class BSShapeCollection : IDisposable if (prim.IsSolid) { bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, - prim.LocalID, prim.ForcePosition, prim.ForceOrientation); + prim.LocalID, prim.RawPosition, prim.RawOrientation); DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } else -- cgit v1.1 From b0eccd5044b1a20b995a62d6fb76fdd73b712f9a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 2 Nov 2012 09:53:41 -0700 Subject: BulletSim: debugging of compound shape implementation of linksets. Add compound shape creation and freeing in shape manager. Add optional taint-time execution method and update code to use it. Add API2 linkage for more compound shape methods (get num, get/remove by index, ...) Modify perferred shape return so linkset children can have differet shapes than root. Add Position and Orientation calls to linksets so children can be moved around by the linkset by its own calculation. Allows for very general linkset implementations. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 13 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 19 ++- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 106 ++++++++++---- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 12 ++ .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 52 +++---- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 12 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 152 ++++++++++++++++----- .../Physics/BulletSPlugin/BSTerrainManager.cs | 21 +-- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 15 +- 10 files changed, 274 insertions(+), 132 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 9e1206a..2a5397e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -200,7 +200,9 @@ public sealed class BSCharacter : BSPhysObject } // I want the physics engine to make an avatar capsule public override ShapeData.PhysicsShapeType PreferredPhysicalShape - { get { return ShapeData.PhysicsShapeType.SHAPE_AVATAR; } } + { + get {return ShapeData.PhysicsShapeType.SHAPE_AVATAR; } + } public override bool Grabbed { set { _grabbed = value; } @@ -238,6 +240,7 @@ public sealed class BSCharacter : BSPhysObject } public override OMV.Vector3 Position { get { + // Don't refetch the position because this function is called a zillion times // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID); return _position; } @@ -304,15 +307,11 @@ public sealed 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. - BSScene.TaintCallback sanityOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() { DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - }; - if (inTaintTime) - sanityOperation(); - else - PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", sanityOperation); + }); ret = true; } return ret; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 9e0f499..8f973f4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -48,7 +48,8 @@ public abstract class BSLinkset */ // at the moment, there is only one - ret = new BSLinksetConstraints(physScene, parent); + // ret = new BSLinksetConstraints(physScene, parent); + ret = new BSLinksetCompound(physScene, parent); return ret; } @@ -69,10 +70,19 @@ public abstract class BSLinkset protected object m_linksetActivityLock = new Object(); // Some linksets have a preferred physical shape. - // Returns SHAPE_UNKNOWN if there is no preference. - public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape - { get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } } + // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. + public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + { + return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + } + // Linksets move around the children so the linkset might need to compute the child position + public virtual OMV.Vector3 Position(BSPhysObject member) + { return member.RawPosition; } + public virtual OMV.Quaternion Orientation(BSPhysObject member) + { return member.RawOrientation; } + // TODO: does this need to be done for Velocity and RotationalVelocityy? + // We keep the prim's mass in the linkset structure since it could be dependent on other prims protected float m_mass; public float LinksetMass @@ -177,7 +187,6 @@ public abstract class BSLinkset } // Perform an action on each member of the linkset including root prim. - // The action is performed only on the objects that are physically in the linkset. // Depends on the action on whether this should be done at taint time. public delegate bool ForEachMemberAction(BSPhysObject obj); public virtual bool ForEachMember(ForEachMemberAction action) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 638fae1..8b97ebb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -41,18 +41,31 @@ public sealed class BSLinksetCompound : BSLinkset base.Initialize(scene, parent); } + // For compound implimented linksets, if there are children, use compound shape for the root. + public override ShapeData.PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + { + ShapeData.PhysicsShapeType ret = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; + if (IsRoot(requestor) && HasAnyChildren) + { + ret = ShapeData.PhysicsShapeType.SHAPE_COMPOUND; + } + // DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret); + return ret; + } + // When physical properties are changed the linkset needs to recalculate // its internal properties. // This is queued in the 'post taint' queue so the // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { + DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); // Queue to happen after all the other taint processing - PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate() - { - if (HasAnyChildren && IsRoot(requestor)) - RecomputeLinksetCompound(); - }); + PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() + { + if (IsRoot(requestor) && HasAnyChildren) + RecomputeLinksetCompound(); + }); } // The object is going dynamic (physical). Do any setup necessary @@ -63,8 +76,17 @@ public sealed class BSLinksetCompound : BSLinkset // Called at taint-time! public override bool MakeDynamic(BSPhysObject child) { - // What is done for each object in BSPrim is what we want. - return false; + bool ret = false; + DetailLog("{0},BSLinksetCompound.MakeDynamic,call,isChild={1}", child.LocalID, HasChild(child)); + if (HasChild(child)) + { + // Physical children are removed from the world as the shape ofthe root compound + // shape takes over. + BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + ret = true; + } + return ret; } // The object is going static (non-physical). Do any setup necessary for a static linkset. @@ -74,8 +96,17 @@ public sealed class BSLinksetCompound : BSLinkset // Called at taint-time! public override bool MakeStatic(BSPhysObject child) { - // What is done for each object in BSPrim is what we want. - return false; + bool ret = false; + DetailLog("{0},BSLinksetCompound.MakeStatic,call,hasChild={1}", child.LocalID, HasChild(child)); + if (HasChild(child)) + { + // The non-physical children can come back to life. + BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + // Don't force activation so setting of DISABLE_SIMULATION can stay. + BulletSimAPI.Activate2(child.PhysBody.ptr, false); + ret = true; + } + return ret; } // Called at taint-time!! @@ -84,20 +115,35 @@ public sealed class BSLinksetCompound : BSLinkset // Nothing to do for constraints on property updates } + // The children move around in relationship to the root. + // Just grab the current values of wherever it is right now. + public override OMV.Vector3 Position(BSPhysObject member) + { + return BulletSimAPI.GetPosition2(member.PhysBody.ptr); + } + + public override OMV.Quaternion Orientation(BSPhysObject member) + { + return BulletSimAPI.GetOrientation2(member.PhysBody.ptr); + } + // Routine called when rebuilding the body of some member of the linkset. - // Destroy all the constraints have have been made to root and set - // up to rebuild the constraints before the next simulation step. + // Since we don't keep in-physical world relationships, do nothing unless it's a child changing. // Returns 'true' of something was actually removed and would need restoring // Called at taint-time!! public override bool RemoveBodyDependencies(BSPrim child) { bool ret = false; - DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); + DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2},isRoot={3}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child)); - // Cause the current shape to be freed and the new one to be built. - Refresh(LinksetRoot); + if (!IsRoot(child)) + { + // Cause the current shape to be freed and the new one to be built. + Refresh(LinksetRoot); + ret = true; + } return ret; } @@ -139,13 +185,19 @@ public sealed class BSLinksetCompound : BSLinkset LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), child.LocalID, child.PhysBody.ptr.ToString("X")); - // See that the linkset parameters are recomputed at the end of the taint time. - Refresh(LinksetRoot); - } - else - { - // Non-fatal occurance. - // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); + // Cause the child's body to be rebuilt and thus restored to normal operation + child.ForceBodyShapeRebuild(false); + + if (!HasAnyChildren) + { + // The linkset is now empty. The root needs rebuilding. + LinksetRoot.ForceBodyShapeRebuild(false); + } + else + { + // Schedule a rebuild of the linkset before the next simulation tick. + Refresh(LinksetRoot); + } } return; } @@ -158,16 +210,18 @@ public sealed class BSLinksetCompound : BSLinkset // Called at taint time!! private void RecomputeLinksetCompound() { - // Release the existing shape - PhysicsScene.Shapes.DereferenceShape(LinksetRoot.PhysShape, true, null); - + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},numChildren={2}", + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), NumberOfChildren); + + LinksetRoot.ForceBodyShapeRebuild(true); + float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass); // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}", + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,end,rBody={1},linksetMass={2}", LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 65aed77..67a59ef 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -84,6 +84,18 @@ public sealed class BSLinksetConstraints : BSLinkset // Nothing to do for constraints on property updates } + // The children of the linkset are moved around by the constraints. + // Just grab the current values of wherever it is right now. + public override OMV.Vector3 Position(BSPhysObject member) + { + return BulletSimAPI.GetPosition2(member.PhysBody.ptr); + } + + public override OMV.Quaternion Orientation(BSPhysObject member) + { + return BulletSimAPI.GetOrientation2(member.PhysBody.ptr); + } + // Routine called when rebuilding the body of some member of the linkset. // Destroy all the constraints have have been made to root and set // up to rebuild the constraints before the next simulation step. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 65d7f34..7127aaf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -81,7 +81,9 @@ public abstract class BSPhysObject : PhysicsActor // Some types of objects have preferred physical representations. // Returns SHAPE_UNKNOWN if there is no preference. public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape - { get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } } + { + get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } + } // When the physical properties are updated, an EntityProperty holds the update values. // Keep the current and last EntityProperties to enable computation of differences diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 1754be6..af403aa 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -173,20 +173,16 @@ public sealed class BSPrim : BSPhysObject } // Whatever the linkset wants is what I want. public override ShapeData.PhysicsShapeType PreferredPhysicalShape - { get { return Linkset.PreferredPhysicalShape; } } + { get { return Linkset.PreferredPhysicalShape(this); } } public override bool ForceBodyShapeRebuild(bool inTaintTime) { LastAssetBuildFailed = false; - BSScene.TaintCallback rebuildOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() { _mass = CalculateMass(); // changing the shape changes the mass CreateGeomAndObject(true); - }; - if (inTaintTime) - rebuildOperation(); - else - PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", rebuildOperation); + }); return true; } public override bool Grabbed { @@ -263,9 +259,9 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 Position { get { + // child prims move around based on their parent. Need to get the latest location if (!Linkset.IsRoot(this)) - // child prims move around based on their parent. Need to get the latest location - _position = BulletSimAPI.GetPosition2(PhysBody.ptr); + _position = Linkset.Position(this); // don't do the GetObjectPosition for root elements because this function is called a zillion times // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); @@ -344,16 +340,11 @@ public sealed class BSPrim : 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. - BSScene.TaintCallback sanityOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck", delegate() { DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); ForcePosition = _position; - }; - if (inTaintTime) - sanityOperation(); - else - PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation); - + }); ret = true; } return ret; @@ -542,10 +533,10 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Quaternion Orientation { get { + // Children move around because tied to parent. Get a fresh value. if (!Linkset.IsRoot(this)) { - // Children move around because tied to parent. Get a fresh value. - _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); + _orientation = Linkset.Orientation(this); } return _orientation; } @@ -946,7 +937,7 @@ public sealed class BSPrim : BSPhysObject m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); return; } - BSScene.TaintCallback addForceOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { OMV.Vector3 fSum = OMV.Vector3.Zero; lock (m_accumulatedForces) @@ -961,11 +952,7 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); - }; - if (inTaintTime) - addForceOperation(); - else - PhysicsScene.TaintedObject("BSPrim.AddForce", addForceOperation); + }); } private List m_accumulatedAngularForces = new List(); @@ -985,7 +972,7 @@ public sealed class BSPrim : BSPhysObject m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); return; } - BSScene.TaintCallback addAngularForceOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() { OMV.Vector3 fSum = OMV.Vector3.Zero; lock (m_accumulatedAngularForces) @@ -1003,26 +990,19 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); _torque = fSum; } - }; - if (inTaintTime) - addAngularForceOperation(); - else - PhysicsScene.TaintedObject("BSPrim.AddAngularForce", addAngularForceOperation); + }); } // A torque impulse. public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) { OMV.Vector3 applyImpulse = impulse; - BSScene.TaintCallback applyTorqueImpulseOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() { DetailLog("{0},BSPrim.ApplyTorqueImpulse,taint,tImpulse={1}", LocalID, applyImpulse); BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); - }; - if (inTaintTime) - applyTorqueImpulseOperation(); - else - PhysicsScene.TaintedObject("BSPrim.ApplyTorqueImpulse", applyTorqueImpulseOperation); + }); } + public override void SetMomentum(OMV.Vector3 momentum) { // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index cc5dbb2..dcfcb83 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -692,6 +692,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters return; } + // Sometimes a potentially tainted operation can be used in and out of taint time. + // This routine executes the command immediately if in taint-time otherwise it is queued. + public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback) + { + if (inTaintTime) + callback(); + else + TaintedObject(ident, callback); + } + // When someone tries to change a property on a BSPrim or BSCharacter, the object queues // a callback into itself to do the actual property change. That callback is called // here just before the physics engine is called to step the simulation. @@ -1438,7 +1448,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { PhysicsLogging.Write(msg, args); // Add the Flush() if debugging crashes to get all the messages written out. - // PhysicsLogging.Flush(); + PhysicsLogging.Flush(); } // Used to fill in the LocalID when there isn't one. It's the correct number of characters. public const string DetailLogZero = "0000000000"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index e131919..107befe 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -122,18 +122,14 @@ public sealed class BSShapeCollection : IDisposable lock (m_collectionActivityLock) { DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body); - BSScene.TaintCallback createOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() { if (!BulletSimAPI.IsInWorld2(body.ptr)) { BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); } - }; - if (inTaintTime) - createOperation(); - else - PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation); + }); } } @@ -146,7 +142,7 @@ public sealed class BSShapeCollection : IDisposable lock (m_collectionActivityLock) { - BSScene.TaintCallback removeOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() { DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", body.ID, body.ptr.ToString("X"), inTaintTime); @@ -159,12 +155,7 @@ public sealed class BSShapeCollection : IDisposable // Zero any reference to the shape so it is not freed when the body is deleted. BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); - }; - // If already in taint-time, do the operations now. Otherwise queue for later. - if (inTaintTime) - removeOperation(); - else - PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation); + }); } } @@ -238,7 +229,7 @@ public sealed class BSShapeCollection : IDisposable if (shape.ptr == IntPtr.Zero) return; - BSScene.TaintCallback dereferenceOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() { if (shape.ptr != IntPtr.Zero) { @@ -270,18 +261,7 @@ public sealed class BSShapeCollection : IDisposable } } } - }; - if (inTaintTime) - { - lock (m_collectionActivityLock) - { - dereferenceOperation(); - } - } - else - { - PhysicsScene.TaintedObject("BSShapeCollection.DereferenceShape", dereferenceOperation); - } + }); } // Count down the reference count for a mesh shape @@ -311,7 +291,10 @@ public sealed class BSShapeCollection : IDisposable { hullDesc.referenceCount--; // TODO: release the Bullet storage (aging old entries?) + + // Tell upper layers that, if they have dependencies on this shape, this link is going away if (shapeCallback != null) shapeCallback(shape); + hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}", @@ -320,10 +303,48 @@ public sealed class BSShapeCollection : IDisposable } // Remove a reference to a compound shape. + // Taking a compound shape apart is a little tricky because if you just delete the + // physical object, it will free all the underlying children. We can't do that because + // they could be shared. So, this removes each of the children from the compound and + // dereferences them separately before destroying the compound collision object itself. // Called at taint-time. private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) { - // Compound shape is made of a bunch of meshes and natives. + if (!BulletSimAPI.IsCompound2(shape.ptr)) + { + // Failed the sanity check!! + PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", + LogHeader, shape.type, shape.ptr.ToString("X")); + DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", + BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); + return; + } + int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); + for (int ii = 0; ii < numChildren; ii++) + { + IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); + DereferenceAnonCollisionShape(childShape); + } + BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); + } + + // Sometimes we have a pointer to a collision shape but don't know what type it is. + // Figure out type and call the correct dereference routine. + // This is coming from a compound shape that we created so we know it is either native or mesh. + // Called at taint-time. + private void DereferenceAnonCollisionShape(IntPtr cShape) + { + BulletShape shapeInfo = new BulletShape(cShape, ShapeData.PhysicsShapeType.SHAPE_MESH); + if (BulletSimAPI.IsCompound2(cShape)) + shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND; + + if (BulletSimAPI.IsNativeShape2(cShape)) + { + shapeInfo.isNativeShape = true; + shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) + } + + DereferenceShape(shapeInfo, true, null); } // Create the geometry information in Bullet for later use. @@ -338,10 +359,8 @@ public sealed class BSShapeCollection : IDisposable { bool ret = false; bool haveShape = false; - bool nativeShapePossible = true; - PrimitiveBaseShape pbs = prim.BaseShape; - if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) + if (!haveShape && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) { // an avatar capsule is close to a native shape (it is not shared) ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, @@ -350,6 +369,31 @@ public sealed class BSShapeCollection : IDisposable ret = true; haveShape = true; } + + // Compound shapes are handled special as they are rebuilt from scratch. + // This isn't too great a hardship since most of the child shapes will already been created. + if (!haveShape && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND) + { + ret = GetReferenceToCompoundShape(prim, shapeCallback); + DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); + haveShape = true; + } + + if (!haveShape) + { + ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback); + } + + return ret; + } + + private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + bool ret = false; + bool haveShape = false; + bool nativeShapePossible = true; + PrimitiveBaseShape pbs = prim.BaseShape; + // If the prim attributes are simple, this could be a simple Bullet native shape if (!haveShape && pbs != null @@ -363,6 +407,7 @@ public sealed class BSShapeCollection : IDisposable && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) { + // It doesn't look like Bullet scales spheres so make sure the scales are all equal if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) { @@ -378,7 +423,7 @@ public sealed class BSShapeCollection : IDisposable prim.LocalID, forceRebuild, prim.PhysShape); } } - if (pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) + if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) { haveShape = true; if (forceRebuild @@ -393,9 +438,10 @@ public sealed class BSShapeCollection : IDisposable } } } + // If a simple shape is not happening, create a mesh and possibly a hull. // Note that if it's a native shape, the check for physical/non-physical is not - // made. Native shapes are best used in either case. + // made. Native shapes work in either case. if (!haveShape && pbs != null) { if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) @@ -487,7 +533,7 @@ public sealed class BSShapeCollection : IDisposable if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) return false; - DetailLog("{0},BSShapeCollection.CreateGeomMesh,create,oldKey={1},newKey={2}", + DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); // Since we're recreating new, get rid of the reference to the previous shape @@ -535,7 +581,7 @@ public sealed class BSShapeCollection : IDisposable verticesAsFloats[vi++] = vv.Z; } - // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", + // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, @@ -561,7 +607,7 @@ public sealed class BSShapeCollection : IDisposable if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) return false; - DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", + DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); // Remove usage of the previous shape. @@ -693,6 +739,42 @@ public sealed class BSShapeCollection : IDisposable return; } + // Compound shapes are always built from scratch. + // This shouldn't be to bad since most of the parts will be meshes that had been built previously. + private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + BulletShape cShape = new BulletShape( + BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); + + // The prim's linkset is the source of the children. + // TODO: there is too much knowledge here about the internals of linksets and too much + // dependency on the relationship of compound shapes and linksets (what if we want to use + // compound shapes for something else?). Think through this and clean up so the + // appropriate knowledge is used at the correct software levels. + + // Recreate the geometry of the root prim (might have been a linkset root in the past) + CreateGeomNonSpecial(true, prim, null); + + BSPhysObject rootPrim = prim.Linkset.LinksetRoot; + + prim.Linkset.ForEachMember(delegate(BSPhysObject cPrim) + { + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(rootPrim.RawOrientation); + OMV.Vector3 displacementPos = (cPrim.RawPosition - rootPrim.RawPosition) * invRootOrientation; + OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; + + DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", + prim.LocalID, cPrim.LocalID, cPrim.PhysShape.ptr.ToString("X"), displacementPos, displacementRot); + + BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); + return false; + }); + + prim.PhysShape = cShape; + + return true; + } + // Create a hash of all the shape parameters to be used as a key // for this particular shape. private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 11298fe..7c34af2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -238,7 +238,7 @@ public sealed class BSTerrainManager DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,call,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}", BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY); - BSScene.TaintCallback rebuildOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateOrCreateTerrain:UpdateExisting", delegate() { if (MegaRegionParentPhysicsScene != null) { @@ -337,14 +337,7 @@ public sealed class BSTerrainManager BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); m_terrainModified = true; - }; - - // There is the option to do the changes now (we're already in 'taint time'), or - // to do the Bullet operations later. - if (inTaintTime) - rebuildOperation(); - else - PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation); + }); } else { @@ -364,7 +357,7 @@ public sealed class BSTerrainManager BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); // Code that must happen at taint-time - BSScene.TaintCallback createOperation = delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateOrCreateTerrain:NewTerrain", delegate() { DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y); // Create a new mapInfo that will be filled with the new info @@ -377,13 +370,7 @@ public sealed class BSTerrainManager UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true); m_terrainModified = true; - }; - - // If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time. - if (inTaintTime) - createOperation(); - else - PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation); + }); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 3b6355c..143b8be 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -399,8 +399,6 @@ public enum CollisionFilterGroups : uint }; - - // 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 @@ -618,10 +616,19 @@ public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float public static extern IntPtr CreateCompoundShape2(IntPtr sim); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot); +public static extern int GetNumberOfCompoundChildren2(IntPtr cShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void AddChildShapeToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape); +public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); -- cgit v1.1 From 1dc23b2b9713f4099534ae0d08c2caf5c8b036b4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 2 Nov 2012 10:35:12 -0700 Subject: BulletSim: parameterize selection of linkset implementation --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 28 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 5 ++++ .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 8f973f4..3a92f93 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -36,21 +36,29 @@ public abstract class BSLinkset { // private static string LogHeader = "[BULLETSIM LINKSET]"; + public enum LinksetImplementation + { + Constraint = 0, // linkset tied together with constraints + Compound = 1, // linkset tied together as a compound object + Manual = 2 // linkset tied together manually (code moves all the pieces) + } // Create the correct type of linkset for this child public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) { BSLinkset ret = null; - /* - if (parent.IsPhysical) - ret = new BSLinksetConstraints(physScene, parent); - else - ret = new BSLinksetManual(physScene, parent); - */ - - // at the moment, there is only one - // ret = new BSLinksetConstraints(physScene, parent); - ret = new BSLinksetCompound(physScene, parent); + switch ((int)physScene.Params.linksetImplementation) + { + case (int)LinksetImplementation.Compound: + ret = new BSLinksetCompound(physScene, parent); + break; + case (int)LinksetImplementation.Manual: + // ret = new BSLinksetManual(physScene, parent); + break; + default: + ret = new BSLinksetConstraints(physScene, parent); + break; + } return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index dcfcb83..13aa860 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1214,6 +1214,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].numberOfSolverIterations; }, (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound)", + (float)BSLinkset.LinksetImplementation.Constraint, + (s,cf,p,v) => { s.m_params[0].linksetImplementation = cf.GetFloat(p,v); }, + (s) => { return s.m_params[0].linksetImplementation; }, + (s,p,l,v) => { s.m_params[0].linksetImplementation = v; } ), new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", ConfigurationParameters.numericFalse, (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 143b8be..ac6d2b2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -300,6 +300,7 @@ public struct ConfigurationParameters public float shouldEnableFrictionCaching; public float numberOfSolverIterations; + public float linksetImplementation; public float linkConstraintUseFrameOffset; public float linkConstraintEnableTransMotor; public float linkConstraintTransMotorMaxVel; -- cgit v1.1 From 498ea76e637961d8b4e3d39b758f7f2dea2fe998 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 2 Nov 2012 17:22:34 -0700 Subject: BulletSim: Move construction of compound linkset from ShapeCollection into LinksetCompound where it should be. Create meshes for native shapes when part of a compound linkset because scale is currently per object and not per collision shape. Don't schedule a LinksetCompound refresh if just changing properties. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 72 ++++++++++++++---- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 24 +++++- .../Physics/BulletSPlugin/BSShapeCollection.cs | 85 +++++++++++----------- 3 files changed, 120 insertions(+), 61 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8b97ebb..adf4aff 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -34,7 +34,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public sealed class BSLinksetCompound : BSLinkset { - // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; + private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; public BSLinksetCompound(BSScene scene, BSPhysObject parent) { @@ -59,6 +59,12 @@ public sealed class BSLinksetCompound : BSLinkset // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { + // External request for Refresh (from BSPrim) is not necessary + // InternalRefresh(requestor); + } + + private void InternalRefresh(BSPhysObject requestor) + { DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() @@ -135,13 +141,13 @@ public sealed class BSLinksetCompound : BSLinkset { bool ret = false; - DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2},isRoot={3}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child)); + DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child)); if (!IsRoot(child)) { // Cause the current shape to be freed and the new one to be built. - Refresh(LinksetRoot); + InternalRefresh(LinksetRoot); ret = true; } @@ -169,7 +175,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); // Cause constraints and assorted properties to be recomputed before the next simulation step. - Refresh(LinksetRoot); + InternalRefresh(LinksetRoot); } return; } @@ -196,34 +202,68 @@ public sealed class BSLinksetCompound : BSLinkset else { // Schedule a rebuild of the linkset before the next simulation tick. - Refresh(LinksetRoot); + InternalRefresh(LinksetRoot); } } return; } - - // Call each of the constraints that make up this linkset and recompute the - // various transforms and variables. Create constraints of not created yet. - // Called before the simulation step to make sure the constraint based linkset + // Called before the simulation step to make sure the compound based linkset // is all initialized. + // Constraint linksets are rebuilt every time. + // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! private void RecomputeLinksetCompound() { - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},numChildren={2}", - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), NumberOfChildren); - + // Cause the root shape to be rebuilt as a compound object with just the root in it LinksetRoot.ForceBodyShapeRebuild(true); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", + LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); + + ForEachMember(delegate(BSPhysObject cPrim) + { + if (!IsRoot(cPrim)) + { + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); + OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; + + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", + LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, displacementPos, displacementRot); + + if (cPrim.PhysShape.isNativeShape) + { + // Native shapes are not shared so we need to create a new one. + // A mesh or hull is created because scale is not available on a native shape. + // (TODO: Bullet does have a btScaledCollisionShape. Can that be used?) + BulletShape saveShape = cPrim.PhysShape; + PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); + BulletShape newShape = cPrim.PhysShape; + cPrim.PhysShape = saveShape; + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot); + } + else + { + // For the shared shapes (meshes and hulls) just use the shape in the child + if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) + { + PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", + LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); + } + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); + } + } + return false; + }); + + float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass); // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,end,rBody={1},linksetMass={2}", - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); - } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 13aa860..de35359 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -116,6 +116,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // True if initialized and ready to do simulation steps private bool m_initialized = false; + // Flag which is true when processing taints. + // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. + public bool InTaintTime { get; private set; } + // Pinned memory used to pass step information between managed and unmanaged private int m_maxCollisionsPerFrame; private CollisionDesc[] m_collisionArray; @@ -270,6 +274,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters TerrainManager = new BSTerrainManager(this); TerrainManager.CreateInitialGroundPlaneAndTerrain(); + m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)Params.linksetImplementation); + + InTaintTime = false; m_initialized = true; } @@ -707,8 +714,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // here just before the physics engine is called to step the simulation. public void ProcessTaints() { + InTaintTime = true; ProcessRegularTaints(); ProcessPostTaintTaints(); + InTaintTime = false; } private void ProcessRegularTaints() @@ -851,6 +860,17 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } + public bool AssertInTaintTime(string whereFrom) + { + if (!InTaintTime) + { + DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); + m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); + Util.PrintCallStack(); + } + return InTaintTime; + } + #endregion // Taints #region Vehicles @@ -1214,8 +1234,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].numberOfSolverIterations; }, (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), - new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound)", - (float)BSLinkset.LinksetImplementation.Constraint, + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", + (float)BSLinkset.LinksetImplementation.Compound, (s,cf,p,v) => { s.m_params[0].linksetImplementation = cf.GetFloat(p,v); }, (s) => { return s.m_params[0].linksetImplementation; }, (s,p,l,v) => { s.m_params[0].linksetImplementation = v; } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 107befe..662b19d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -92,6 +92,8 @@ public sealed class BSShapeCollection : IDisposable public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) { + PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); + bool ret = false; // This lock could probably be pushed down lower but building shouldn't take long @@ -121,7 +123,7 @@ public sealed class BSShapeCollection : IDisposable { lock (m_collectionActivityLock) { - DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body); + DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() { if (!BulletSimAPI.IsInWorld2(body.ptr)) @@ -165,7 +167,7 @@ public sealed class BSShapeCollection : IDisposable // Meshes and hulls for the same shape have the same hash key. // NOTE that native shapes are not added to the mesh list or removed. // Returns 'true' if this is the initial reference to the shape. Otherwise reused. - private bool ReferenceShape(BulletShape shape) + public bool ReferenceShape(BulletShape shape) { bool ret = false; switch (shape.type) @@ -276,8 +278,8 @@ public sealed class BSShapeCollection : IDisposable if (shapeCallback != null) shapeCallback(shape); meshDesc.lastReferenced = System.DateTime.Now; Meshes[shape.shapeKey] = meshDesc; - DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}", - BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); + DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", + BSScene.DetailLogZero, shape, meshDesc.referenceCount); } } @@ -297,8 +299,8 @@ public sealed class BSShapeCollection : IDisposable hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; - DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}", - BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); + DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", + BSScene.DetailLogZero, shape, hullDesc.referenceCount); } } @@ -319,8 +321,11 @@ public sealed class BSShapeCollection : IDisposable BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); return; } + int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); - for (int ii = 0; ii < numChildren; ii++) + DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); + + for (int ii = numChildren - 1; ii >= 0; ii--) { IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); DereferenceAnonCollisionShape(childShape); @@ -343,6 +348,7 @@ public sealed class BSShapeCollection : IDisposable shapeInfo.isNativeShape = true; shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) } + DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); DereferenceShape(shapeInfo, true, null); } @@ -440,23 +446,32 @@ public sealed class BSShapeCollection : IDisposable } // If a simple shape is not happening, create a mesh and possibly a hull. + if (!haveShape && pbs != null) + { + ret = CreateGeomMeshOrHull(prim, shapeCallback); + } + + return ret; + } + + public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + + bool ret = false; // Note that if it's a native shape, the check for physical/non-physical is not // made. Native shapes work in either case. - if (!haveShape && pbs != null) + if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) { - if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) - { - // Update prim.BSShape to reference a hull of this shape. - ret = GetReferenceToHull(prim,shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", - prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); - } - else - { - ret = GetReferenceToMesh(prim, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", - prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); - } + // Update prim.BSShape to reference a hull of this shape. + ret = GetReferenceToHull(prim,shapeCallback); + DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", + prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); + } + else + { + ret = GetReferenceToMesh(prim, shapeCallback); + DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", + prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } return ret; } @@ -743,32 +758,16 @@ public sealed class BSShapeCollection : IDisposable // This shouldn't be to bad since most of the parts will be meshes that had been built previously. private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { + // Remove reference to the old shape + // Don't need to do this as the shape is freed when we create the new root shape below. + // DereferenceShape(prim.PhysShape, true, shapeCallback); + BulletShape cShape = new BulletShape( BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); - // The prim's linkset is the source of the children. - // TODO: there is too much knowledge here about the internals of linksets and too much - // dependency on the relationship of compound shapes and linksets (what if we want to use - // compound shapes for something else?). Think through this and clean up so the - // appropriate knowledge is used at the correct software levels. - - // Recreate the geometry of the root prim (might have been a linkset root in the past) + // Create the shape for the root prim and add it to the compound shape CreateGeomNonSpecial(true, prim, null); - - BSPhysObject rootPrim = prim.Linkset.LinksetRoot; - - prim.Linkset.ForEachMember(delegate(BSPhysObject cPrim) - { - OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(rootPrim.RawOrientation); - OMV.Vector3 displacementPos = (cPrim.RawPosition - rootPrim.RawPosition) * invRootOrientation; - OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; - - DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", - prim.LocalID, cPrim.LocalID, cPrim.PhysShape.ptr.ToString("X"), displacementPos, displacementRot); - - BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); - return false; - }); + BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); prim.PhysShape = cShape; -- cgit v1.1 From 894bb4893b8bb269f8561737e4603a9b31183f2c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 3 Nov 2012 18:26:00 -0700 Subject: BulletSim: search the mesh and hull lists to find shapes if type is not known. This makes sure the correct accounting is done for the particular shape. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 10 +- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 102 ++++++++++++++++++--- 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index adf4aff..6e68695 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -134,7 +134,7 @@ public sealed class BSLinksetCompound : BSLinkset } // Routine called when rebuilding the body of some member of the linkset. - // Since we don't keep in-physical world relationships, do nothing unless it's a child changing. + // Since we don't keep in world relationships, do nothing unless it's a child changing. // Returns 'true' of something was actually removed and would need restoring // Called at taint-time!! public override bool RemoveBodyDependencies(BSPrim child) @@ -221,10 +221,12 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); + // Add a shape for each of the other children in the linkset ForEachMember(delegate(BSPhysObject cPrim) { if (!IsRoot(cPrim)) { + // Each child position and rotation is given relative to the root. OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; @@ -245,7 +247,7 @@ public sealed class BSLinksetCompound : BSLinkset } else { - // For the shared shapes (meshes and hulls) just use the shape in the child + // For the shared shapes (meshes and hulls), just use the shape in the child. if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) { PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", @@ -254,10 +256,10 @@ public sealed class BSLinksetCompound : BSLinkset BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); } } - return false; + return false; // 'false' says to move onto the next child in the list }); - + // With all of the linkset packed into the root prim, it has the mass of everyone. float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 67a59ef..d2387fb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -294,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass); - // DEBUG: see of inter-linkset collisions are causing problems + // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index de35359..c2e0ef1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1472,7 +1472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public void DetailLog(string msg, params Object[] args) { PhysicsLogging.Write(msg, args); - // Add the Flush() if debugging crashes to get all the messages written out. + // Add the Flush() if debugging crashes. Gets all the messages written out. PhysicsLogging.Flush(); } // Used to fill in the LocalID when there isn't one. It's the correct number of characters. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 662b19d..4a31c7d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -48,6 +48,7 @@ public sealed class BSShapeCollection : IDisposable public IntPtr ptr; public int referenceCount; public DateTime lastReferenced; + public UInt64 shapeKey; } // Description of a hull. @@ -57,6 +58,7 @@ public sealed class BSShapeCollection : IDisposable public IntPtr ptr; public int referenceCount; public DateTime lastReferenced; + public UInt64 shapeKey; } // The sharable set of meshes and hulls. Indexed by their shape hash. @@ -116,7 +118,7 @@ public sealed class BSShapeCollection : IDisposable return ret; } - // Track another user of a body + // Track another user of a body. // We presume the caller has allocated the body. // Bodies only have one user so the body is just put into the world if not already there. public void ReferenceBody(BulletBody body, bool inTaintTime) @@ -146,13 +148,16 @@ public sealed class BSShapeCollection : IDisposable { PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() { - DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", - body.ID, body.ptr.ToString("X"), inTaintTime); + DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", + body.ID, body, inTaintTime); // If the caller needs to know the old body is going away, pass the event up. if (bodyCallback != null) bodyCallback(body); - // It may have already been removed from the world in which case the next is a NOOP. - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); + if (BulletSimAPI.IsInWorld2(body.ptr)) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); + DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); + } // Zero any reference to the shape so it is not freed when the body is deleted. BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); @@ -185,6 +190,7 @@ public sealed class BSShapeCollection : IDisposable { // This is a new reference to a mesh meshDesc.ptr = shape.ptr; + meshDesc.shapeKey = shape.shapeKey; // We keep a reference to the underlying IMesh data so a hull can be built meshDesc.referenceCount = 1; DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", @@ -207,6 +213,7 @@ public sealed class BSShapeCollection : IDisposable { // This is a new reference to a hull hullDesc.ptr = shape.ptr; + hullDesc.shapeKey = shape.shapeKey; hullDesc.referenceCount = 1; DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); @@ -306,7 +313,7 @@ public sealed class BSShapeCollection : IDisposable // Remove a reference to a compound shape. // Taking a compound shape apart is a little tricky because if you just delete the - // physical object, it will free all the underlying children. We can't do that because + // physical shape, it will free all the underlying children. We can't do that because // they could be shared. So, this removes each of the children from the compound and // dereferences them separately before destroying the compound collision object itself. // Called at taint-time. @@ -335,22 +342,53 @@ public sealed class BSShapeCollection : IDisposable // Sometimes we have a pointer to a collision shape but don't know what type it is. // Figure out type and call the correct dereference routine. - // This is coming from a compound shape that we created so we know it is either native or mesh. // Called at taint-time. private void DereferenceAnonCollisionShape(IntPtr cShape) { - BulletShape shapeInfo = new BulletShape(cShape, ShapeData.PhysicsShapeType.SHAPE_MESH); - if (BulletSimAPI.IsCompound2(cShape)) - shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND; + MeshDesc meshDesc; + HullDesc hullDesc; - if (BulletSimAPI.IsNativeShape2(cShape)) + BulletShape shapeInfo = new BulletShape(cShape); + if (TryGetMeshByPtr(cShape, out meshDesc)) + { + shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_MESH; + shapeInfo.shapeKey = meshDesc.shapeKey; + } + else { - shapeInfo.isNativeShape = true; - shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) + if (TryGetHullByPtr(cShape, out hullDesc)) + { + shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_HULL; + shapeInfo.shapeKey = hullDesc.shapeKey; + } + else + { + if (BulletSimAPI.IsCompound2(cShape)) + { + shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND; + } + else + { + if (BulletSimAPI.IsNativeShape2(cShape)) + { + shapeInfo.isNativeShape = true; + shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) + } + } + } } + DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); - DereferenceShape(shapeInfo, true, null); + if (shapeInfo.type != ShapeData.PhysicsShapeType.SHAPE_UNKNOWN) + { + DereferenceShape(shapeInfo, true, null); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", + LogHeader, PhysicsScene.RegionName, cShape.ToString("X")); + } } // Create the geometry information in Bullet for later use. @@ -913,6 +951,42 @@ public sealed class BSShapeCollection : IDisposable return ret; } + private bool TryGetMeshByPtr(IntPtr addr, out MeshDesc outDesc) + { + bool ret = false; + MeshDesc foundDesc = new MeshDesc(); + foreach (MeshDesc md in Meshes.Values) + { + if (md.ptr == addr) + { + foundDesc = md; + ret = true; + break; + } + + } + outDesc = foundDesc; + return ret; + } + + private bool TryGetHullByPtr(IntPtr addr, out HullDesc outDesc) + { + bool ret = false; + HullDesc foundDesc = new HullDesc(); + foreach (HullDesc hd in Hulls.Values) + { + if (hd.ptr == addr) + { + foundDesc = hd; + ret = true; + break; + } + + } + outDesc = foundDesc; + return ret; + } + private void DetailLog(string msg, params Object[] args) { if (PhysicsScene.PhysicsLogging.Enabled) -- cgit v1.1 From 79f7c466a116bf368423d4e18163f34fd8d66ce1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 3 Nov 2012 21:08:39 -0700 Subject: BulletSim: fix compound linkset crash by not freeing shape of child prims. Remove all compilation warnings (mostly 'protected' in sealed classes.) Add the dynamicAabbEnable parameter to creation of compound shapes. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 6 +++--- .../Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 11 ++++++----- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 3 +++ OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- .../Region/Physics/BulletSPlugin/BSShapeCollection.cs | 16 ++++++++++------ OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 2 +- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 38609e3..819635a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -89,7 +89,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin //Angular properties private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor - private int m_angularMotorApply = 0; // application frame counter + // private int m_angularMotorApply = 0; // application frame counter private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate @@ -199,7 +199,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.ANGULAR_MOTOR_DIRECTION: m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - m_angularMotorApply = 100; + // m_angularMotorApply = 100; break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); @@ -229,7 +229,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_angularMotorApply = 100; + // m_angularMotorApply = 100; break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6e68695..12c6d7a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -83,8 +83,8 @@ public sealed class BSLinksetCompound : BSLinkset public override bool MakeDynamic(BSPhysObject child) { bool ret = false; - DetailLog("{0},BSLinksetCompound.MakeDynamic,call,isChild={1}", child.LocalID, HasChild(child)); - if (HasChild(child)) + DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); + if (!IsRoot(child)) { // Physical children are removed from the world as the shape ofthe root compound // shape takes over. @@ -103,8 +103,8 @@ public sealed class BSLinksetCompound : BSLinkset public override bool MakeStatic(BSPhysObject child) { bool ret = false; - DetailLog("{0},BSLinksetCompound.MakeStatic,call,hasChild={1}", child.LocalID, HasChild(child)); - if (HasChild(child)) + DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); + if (!IsRoot(child)) { // The non-physical children can come back to life. BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); @@ -240,6 +240,7 @@ public sealed class BSLinksetCompound : BSLinkset // A mesh or hull is created because scale is not available on a native shape. // (TODO: Bullet does have a btScaledCollisionShape. Can that be used?) BulletShape saveShape = cPrim.PhysShape; + cPrim.PhysShape.ptr = IntPtr.Zero; // Don't let the create free the child's shape PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; @@ -263,7 +264,7 @@ public sealed class BSLinksetCompound : BSLinkset float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass); - // DEBUG: see of inter-linkset collisions are causing problems + // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets. // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index af403aa..aaa0d93 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -703,6 +703,9 @@ public sealed class BSPrim : BSPhysObject // For good measure, make sure the transform is set through to the motion state BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + // Center of mass is at the center of the object + BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); + // A dynamic object has mass UpdatePhysicalMassProperties(RawMass); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index c2e0ef1..740f339 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1391,7 +1391,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // If the local ID is APPLY_TO_NONE, just change the default value // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs // If the localID is a specific object, apply the parameter change to only that object - protected void UpdateParameterObject(ref float defaultLoc, string parm, uint localID, float val) + private void UpdateParameterObject(ref float defaultLoc, string parm, uint localID, float val) { List objectIDs = new List(); switch (localID) @@ -1416,7 +1416,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } // schedule the actual updating of the paramter to when the phys engine is not busy - protected void TaintedUpdateParameter(string parm, List lIDs, float val) + private void TaintedUpdateParameter(string parm, List lIDs, float val) { float xval = val; List xlIDs = lIDs; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 4a31c7d..29a23c0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -38,7 +38,7 @@ public sealed class BSShapeCollection : IDisposable { private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]"; - protected BSScene PhysicsScene { get; set; } + private BSScene PhysicsScene { get; set; } private Object m_collectionActivityLock = new Object(); @@ -103,11 +103,12 @@ public sealed class BSShapeCollection : IDisposable { // Do we have the correct geometry for this type of object? // Updates prim.BSShape with information/pointers to shape. - // CreateGeom returns 'true' of BSShape as changed to a new shape. + // Returns 'true' of BSShape is changed to a new shape. bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback); // If we had to select a new shape geometry for the object, // rebuild the body around it. // Updates prim.BSBody with information/pointers to requested body + // Returns 'true' if BSBody was changed. bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.PhysShape, bodyCallback); ret = newGeom || newBody; @@ -431,6 +432,7 @@ public sealed class BSShapeCollection : IDisposable return ret; } + // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; @@ -797,15 +799,17 @@ public sealed class BSShapeCollection : IDisposable private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { // Remove reference to the old shape - // Don't need to do this as the shape is freed when we create the new root shape below. + // Don't need to do this as the shape is freed when the new root shape is created below. // DereferenceShape(prim.PhysShape, true, shapeCallback); BulletShape cShape = new BulletShape( - BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); + BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); - // Create the shape for the root prim and add it to the compound shape - CreateGeomNonSpecial(true, prim, null); + // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. + CreateGeomMeshOrHull(prim, shapeCallback); BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); + DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", + prim.LocalID, cShape, prim.PhysShape); prim.PhysShape = cShape; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index ac6d2b2..702bd77 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -614,7 +614,7 @@ public static extern bool IsNativeShape2(IntPtr shape); public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateCompoundShape2(IntPtr sim); +public static extern IntPtr CreateCompoundShape2(IntPtr sim, bool enableDynamicAabbTree); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern int GetNumberOfCompoundChildren2(IntPtr cShape); -- cgit v1.1 From 895d28f14dd2802a0af2349d8f7c34643a8dae06 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 3 Nov 2012 21:28:23 -0700 Subject: BulletSim: update the DLLs and SOs --- bin/lib32/BulletSim.dll | Bin 598016 -> 598528 bytes bin/lib32/libBulletSim.so | Bin 2772770 -> 2773926 bytes bin/lib64/BulletSim.dll | Bin 764416 -> 764928 bytes bin/lib64/libBulletSim.so | Bin 3031859 -> 3033275 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index fbc83e6..0ed960a 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 65d3805..f71c308 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 936368a..701ee4c 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 82fbad6..cc839f6 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From f391d028de3aff0cc49d024d855555253eb8c02c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 4 Nov 2012 22:01:34 +0100 Subject: Add a method to query all registered script constants to allow non-XEngine script engines to use them. --- .../ScriptModuleComms/ScriptModuleCommsModule.cs | 16 ++++++++++++++++ .../Region/Framework/Interfaces/IScriptModuleComms.cs | 2 ++ 2 files changed, 18 insertions(+) diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index 98396ff..dc54c3f 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -361,6 +361,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms return null; } + /// + /// Get all registered constants + /// + public Dictionary GetConstants() + { + Dictionary ret = new Dictionary(); + + lock (m_constants) + { + foreach (KeyValuePair kvp in m_constants) + ret[kvp.Key] = kvp.Value; + } + + return ret; + } + #endregion } diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index 93930ce..70ff954 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; +using System.Collections.Generic; using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces @@ -131,6 +132,7 @@ namespace OpenSim.Region.Framework.Interfaces /// Name of constant /// Value of constant or null if none found. object LookupModConstant(string cname); + Dictionary GetConstants(); // For use ONLY by the script API void RaiseEvent(UUID script, string id, string module, string command, string key); -- cgit v1.1