From 2c5ff9399063080276a23bcd06fb696d653bef2e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Sep 2012 08:11:54 -0700 Subject: BulletSim: Way too many changes in one commit. Many changes to BSDynamic for readability and commentary. Linkset hacking for vehicles: don't over mass the root prim. Add parameter for link constraint solver iterations. Correct uses of timestep in timescale calculations for vehicles. Reorganize code/logic for making objects static and dynamic for readability and use of API2. Changed most calls in BSPrim to use API2 calls (the new way). Avatars do not generate default Bullet collision events but do call up to the simulator for every avatar. Reduces overhead. Objects added to collision list only if they are processing collisions. Reduces overhead especially for large numbers of avatars. Generalize call for water height to GetWaterHeightAtXYZ(). Catch and correct exception getting terrain height when out of bounds. Correct race condition in Terrain Manager where creation wasn't at taint-time. Add API calls for constructing compound shapes. Move NeedsMeshing() logic into object class. Reorganize logic for object meshing to reduce rebuilding of meshs/hulls. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 17 +- .../Region/Physics/BulletSPlugin/BSConstraint.cs | 16 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 218 +++++++++------------ OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 32 ++- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 196 ++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 67 ++++--- .../Physics/BulletSPlugin/BSTerrainManager.cs | 60 +++--- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 29 ++- 9 files changed, 351 insertions(+), 286 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index fa22c78..a9b1365 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -131,8 +131,6 @@ public class BSCharacter : BSPhysObject BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID)); - // avatars get all collisions no matter what (makes walking on ground and such work) - BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); return; @@ -480,11 +478,10 @@ public class BSCharacter : BSPhysObject // Stop collision events public override void UnSubscribeEvents() { _subscribedEventsMs = 0; - // Avatars get all their collision events - // Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() - // { - // BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - // }); + Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() + { + BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + }); } // Return 'true' if someone has subscribed to events public override bool SubscribedEvents() { @@ -532,10 +529,12 @@ public class BSCharacter : BSPhysObject // The collision, if it should be reported to the character, is placed in a collection // that will later be sent to the simulator when SendCollisions() is called. CollisionEventUpdate collisionCollection = null; - public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) + public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) { // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); + bool ret = false; + // The following makes IsColliding() and IsCollidingGround() work _collidingStep = Scene.SimulationStep; if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) @@ -553,8 +552,10 @@ public class BSCharacter : BSPhysObject if (collisionCollection == null) collisionCollection = new CollisionEventUpdate(); collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + ret = true; } } + return ret; } public override void SendCollisions() diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index 2e15ced..1376a29 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -74,6 +74,17 @@ public abstract class BSConstraint : IDisposable return ret; } + public virtual bool SetSolverIterations(float cnt) + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.Ptr, cnt); + ret = true; + } + return ret; + } + public virtual bool CalculateTransforms() { bool ret = false; @@ -96,12 +107,9 @@ public abstract class BSConstraint : IDisposable ret = CalculateTransforms(); if (ret) { - // m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}", - // BSScene.DetailLogZero, Body1.ID, Body2.ID); - // Setting an object's mass to zero (making it static like when it's selected) // automatically disables the constraints. - // If enabled, be sure to set the constraint itself to enabled. + // If the link is enabled, be sure to set the constraint itself to enabled. BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true)); } else diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 8169e99..098fea7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Linear properties private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL - private Vector3 m_dir = Vector3.Zero; // velocity applied to body + private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body private Vector3 m_linearFrictionTimescale = Vector3.Zero; private float m_linearMotorDecayTimescale = 0; private float m_linearMotorTimescale = 0; @@ -475,32 +475,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin frcount = 0; MoveLinear(pTimestep); - MoveAngular(pTimestep); + // MoveAngular(pTimestep); LimitRotation(pTimestep); + // remember the position so next step we can limit absolute movement effects + m_lastPositionVector = m_prim.Position; + VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); }// end Step private void MoveLinear(float pTimestep) { - // requested m_linearMotorDirection is significant - // if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) - if (m_linearMotorDirection.LengthSquared() > 0.0001f) + // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates + // m_lastLinearVelocityVector is the 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_linearMotorTimescale); - // lastLinearVelocityVector is the current body velocity vector? + // 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; - // This will work temporarily, but we really need to compare speed on an axis - // KF: Limit body velocity to applied velocity? // 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; @@ -509,34 +510,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin 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))); + Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep); + // (RA: do not know where the 0.5f comes from) m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; - - /* - Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale; - m_lastLinearVelocityVector += addAmount; - - float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale); - m_linearMotorDirection *= decayfraction; - */ + float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep)); + m_linearMotorDirection *= keepfraction; - VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", - m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); + VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}", + m_prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector); } else { - // if what remains of applied is small, zero it. - // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) - // m_lastLinearVelocityVector = Vector3.Zero; + // if what remains of direction is very small, zero it. m_linearMotorDirection = Vector3.Zero; m_lastLinearVelocityVector = Vector3.Zero; + VDetailLog("{0},MoveLinear,zeroed", m_prim.LocalID); } // convert requested object velocity to object relative vector Quaternion rotq = m_prim.Orientation; - m_dir = m_lastLinearVelocityVector * rotq; + m_newVelocity = m_lastLinearVelocityVector * rotq; // Add the various forces into m_dir which will be our new direction vector (velocity) @@ -544,60 +540,31 @@ namespace OpenSim.Region.Physics.BulletSPlugin // KF: So far I have found no good method to combine a script-requested // .Z velocity and gravity. Therefore only 0g will used script-requested // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. - Vector3 grav = Vector3.Zero; // There is some gravity, make a gravity force vector that is applied after object velocity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy); + Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy)); + + /* + * RA: Not sure why one would do this // Preserve the current Z velocity Vector3 vel_now = m_prim.Velocity; m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity + */ Vector3 pos = m_prim.Position; - Vector3 posChange = pos; // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); - double Zchange = Math.Abs(posChange.Z); - if (m_BlockingEndPoint != Vector3.Zero) - { - bool changed = false; - if (pos.X >= (m_BlockingEndPoint.X - (float)1)) - { - pos.X -= posChange.X + 1; - changed = true; - } - if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) - { - pos.Y -= posChange.Y + 1; - changed = true; - } - if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) - { - pos.Z -= posChange.Z + 1; - changed = true; - } - if (pos.X <= 0) - { - pos.X += posChange.X + 1; - changed = true; - } - if (pos.Y <= 0) - { - pos.Y += posChange.Y + 1; - changed = true; - } - if (changed) - { - m_prim.Position = pos; - VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", - m_prim.LocalID, m_BlockingEndPoint, posChange, pos); - } - } // If below the terrain, move us above the ground a little. - if (pos.Z < m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos)) + float terrainHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos); + // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. + // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. + // Vector3 rotatedSize = m_prim.Size * m_prim.Orientation; + // if (rotatedSize.Z < terrainHeight) + if (pos.Z < terrainHeight) { - pos.Z = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2; + pos.Z = terrainHeight + 2; m_prim.Position = pos; - VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); + VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", m_prim.LocalID, terrainHeight, pos); } // Check if hovering @@ -606,11 +573,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; + m_VhoverTargetHeight = m_prim.Scene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { - m_VhoverTargetHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; + m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) { @@ -635,82 +602,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Replace Vertical speed with correction figure if significant if (Math.Abs(herr0) > 0.01f) { - m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); + m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); //KF: m_VhoverEfficiency is not yet implemented } else { - m_dir.Z = 0f; + m_newVelocity.Z = 0f; } } - VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); + VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight); + } -// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped -// m_VhoverTimescale = 0f; // time to acheive height -// pTimestep is time since last frame,in secs + Vector3 posChange = pos - m_lastPositionVector; + if (m_BlockingEndPoint != Vector3.Zero) + { + bool changed = false; + if (pos.X >= (m_BlockingEndPoint.X - (float)1)) + { + pos.X -= posChange.X + 1; + changed = true; + } + if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) + { + pos.Y -= posChange.Y + 1; + changed = true; + } + if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) + { + pos.Z -= posChange.Z + 1; + changed = true; + } + if (pos.X <= 0) + { + pos.X += posChange.X + 1; + changed = true; + } + if (pos.Y <= 0) + { + pos.Y += posChange.Y + 1; + changed = true; + } + if (changed) + { + m_prim.Position = pos; + VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", + m_prim.LocalID, m_BlockingEndPoint, posChange, pos); + } } + float Zchange = Math.Abs(posChange.Z); if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { - //Start Experimental Values if (Zchange > .3) - { grav.Z = (float)(grav.Z * 3); - } if (Zchange > .15) - { grav.Z = (float)(grav.Z * 2); - } if (Zchange > .75) - { grav.Z = (float)(grav.Z * 1.5); - } if (Zchange > .05) - { grav.Z = (float)(grav.Z * 1.25); - } if (Zchange > .025) - { grav.Z = (float)(grav.Z * 1.125); - } - float terraintemp = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos); - float postemp = (pos.Z - terraintemp); + float postemp = (pos.Z - terrainHeight); if (postemp > 2.5f) - { grav.Z = (float)(grav.Z * 1.037125); - } VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); - //End Experimental Values } if ((m_flags & (VehicleFlag.NO_X)) != 0) - { - m_dir.X = 0; - } + m_newVelocity.X = 0; if ((m_flags & (VehicleFlag.NO_Y)) != 0) - { - m_dir.Y = 0; - } + m_newVelocity.Y = 0; if ((m_flags & (VehicleFlag.NO_Z)) != 0) - { - m_dir.Z = 0; - } - - m_lastPositionVector = m_prim.Position; + m_newVelocity.Z = 0; // Apply velocity - m_prim.Velocity = m_dir; + m_prim.Velocity = m_newVelocity; // apply gravity force // Why is this set here? The physics engine already does gravity. // m_prim.AddForce(grav, false); - // m_prim.Force = grav; // Apply friction - Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); - m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; + Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep)); + m_lastLinearVelocityVector *= keepFraction; - VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", - m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); + VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}", + m_prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction); } // end MoveLinear() @@ -735,17 +712,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin // There are m_angularMotorApply steps. Vector3 origAngularVelocity = m_angularMotorVelocity; // ramp up to new value - // current velocity += error / (time to get there / step interval) - // requested speed - last motor speed + // current 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); - VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", - m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); + VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}", + m_prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); - m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected - // velocity may still be acheived. + // This is done so that if script request rate is less than phys frame rate the expected + // velocity may still be acheived. + m_angularMotorApply--; } else { @@ -760,7 +738,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 vertattr = Vector3.Zero; if (m_verticalAttractionTimescale < 300) { - float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); + float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep); // get present body rotation Quaternion rotq = m_prim.Orientation; // make a vector pointing up @@ -863,16 +841,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_rot.Y = 0; changed = true; } - if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) - { - m_rot.X = 0; - m_rot.Y = 0; - changed = true; - } if (changed) + { m_prim.Orientation = m_rot; + VDetailLog("{0},LimitRotation,done,orig={1},new={2}", m_prim.LocalID, rotq, m_rot); + } - VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); } // Invoke the detailed logger and output something if it's enabled. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 5f6601d..dc1de6c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -206,7 +206,7 @@ public class BSLinkset // its internal properties. public void Refresh(BSPhysObject requestor) { - // If there are no children, there aren't any constraints to recompute + // If there are no children, there can't be any constraints to recompute if (!HasAnyChildren) return; @@ -225,11 +225,12 @@ public class BSLinkset // from a linkset to make sure the constraints know about the new mass and // geometry. // Must only be called at taint time!! - private bool RecomputeLinksetConstraintVariables() + private void RecomputeLinksetConstraintVariables() { float linksetMass = LinksetMass; lock (m_linksetActivityLock) { + bool somethingMissing = false; foreach (BSPhysObject child in m_children) { BSConstraint constrain; @@ -241,16 +242,29 @@ public class BSLinkset } else { - // Non-fatal error that can happen when children are being added to the linkset but + // Non-fatal error that happens when children are being added to the linkset but // their constraints have not been created yet. // Caused by the fact that m_children is built at run time but building constraints // happens at taint time. - // m_physicsScene.Logger.ErrorFormat("{0} RecomputeLinksetConstraintVariables: constraint not found for root={1}, child={2}", - // LogHeader, m_linksetRoot.Body.ID, child.Body.ID); + somethingMissing = true; + break; } } + + // If the whole linkset is not here, doesn't make sense to recompute the root prim now. + if (!somethingMissing) + { + // The root prim takes on the weight of the whole linkset + /* + OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(LinksetRoot.BSShape.Ptr, linksetMass); + BulletSimAPI.SetMassProps2(LinksetRoot.BSBody.Ptr, linksetMass, inertia); + OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); + BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); + BulletSimAPI.UpdateInertiaTensor2(LinksetRoot.BSBody.Ptr); + */ + } } - return false; + return; } // I am the root of a linkset and a new child is being added @@ -296,9 +310,9 @@ public class BSLinkset DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); PhysicallyUnlinkAChildFromRoot(rootx, childx); + RecomputeLinksetConstraintVariables(); }); - RecomputeLinksetConstraintVariables(); } else { @@ -377,6 +391,10 @@ public class BSLinkset PhysicsScene.Params.linkConstraintTransMotorMaxVel, PhysicsScene.Params.linkConstraintTransMotorMaxForce); constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); + if (PhysicsScene.Params.linkConstraintSolverIterations != 0f) + { + constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); + } RecomputeLinksetConstraintVariables(); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e411fcb..969c53e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -41,7 +41,7 @@ public abstract class BSPhysObject : PhysicsActor { public abstract BSLinkset Linkset { get; set; } - public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, + public abstract bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); public abstract void SendCollisions(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 6d0af63..481a8db 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -136,11 +136,11 @@ public sealed class BSPrim : BSPhysObject Linkset = new BSLinkset(Scene, this); // a linkset of one _vehicle = new BSDynamics(Scene, this); // add vehicleness _mass = CalculateMass(); - // do the actual object creation at taint time DetailLog("{0},BSPrim.constructor,call", LocalID); + // do the actual object creation at taint time _scene.TaintedObject("BSPrim.create", delegate() { - RecreateGeomAndObject(); + CreateGeomAndObject(true); // Get the pointer to the physical body for this object. // At the moment, we're still letting BulletSim manage the creation and destruction @@ -186,9 +186,10 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setSize", delegate() { _mass = CalculateMass(); // changing size changes the mass - BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); - DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); - RecreateGeomAndObject(); + // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct + // scale and margins are set. + CreateGeomAndObject(true); + DetailLog("{0}: BSPrim.setSize: size={1}, scale={2}, mass={3}, physical={4}", LocalID, _size, _scale, _mass, IsPhysical); }); } } @@ -198,7 +199,7 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setShape", delegate() { _mass = CalculateMass(); // changing the shape changes the mass - RecreateGeomAndObject(); + CreateGeomAndObject(false); }); } } @@ -279,7 +280,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.GetObjectPosition(_scene.WorldID, _localID); + _position = BulletSimAPI.GetPosition2(BSBody.Ptr); // don't do the GetObjectPosition for root elements because this function is called a zillion times // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); @@ -291,7 +292,7 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); + BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); }); } } @@ -302,7 +303,8 @@ public sealed class BSPrim : BSPhysObject { get { - return Linkset.LinksetMass; + // return Linkset.LinksetMass; + return _mass; } } @@ -328,7 +330,6 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setForce", delegate() { DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); - // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); }); } @@ -406,7 +407,7 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setVelocity", delegate() { DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); - BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); + BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity); }); } } @@ -430,7 +431,7 @@ public sealed class BSPrim : BSPhysObject if (!Linkset.IsRoot(this)) { // Children move around because tied to parent. Get a fresh value. - _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); + _orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr); } return _orientation; } @@ -441,7 +442,7 @@ public sealed class BSPrim : BSPhysObject { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); + BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); }); } } @@ -483,31 +484,37 @@ public sealed class BSPrim : BSPhysObject { // If it's becoming dynamic, it will need hullness VerifyCorrectPhysicalShape(); + UpdatePhysicalParameters(); + } + private void UpdatePhysicalParameters() + { + /* // Bullet wants static objects to have a mass of zero float mass = IsStatic ? 0f : _mass; BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); - /* + */ BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr); - // Set up the object physicalness (static or dynamic) - MakeDynamic(); + // Set up the object physicalness (does gravity and collisions move this object) + MakeDynamic(IsStatic); - // Make solid or not and arrange for collisions, etc - MakeSolid(); + // Make solid or not (do things bounce off or pass through this object) + MakeSolid(IsSolid); - m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); + // Arrange for collisions events if the simulator wants them + EnableCollisions(SubscribedEvents()); BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr); - */ // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that // had been automatically disabled when the mass was set to zero. Linkset.Refresh(this); - DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, m_currentCollisionFlags); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3}, cf={4}", + LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags); } // "Making dynamic" means changing to and from static. @@ -515,12 +522,12 @@ public sealed class BSPrim : BSPhysObject // When dynamic, the object can fall and be pushed by others. // This is independent of its 'solidness' which controls what passes through // this object and what interacts with it. - private void MakeDynamic() + private void MakeDynamic(bool makeStatic) { - if (IsStatic) + if (makeStatic) { // Become a Bullet 'static' object type - BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement BulletSimAPI.ClearAllForces2(BSBody.Ptr); // Mass is zero which disables a bunch of physics stuff in Bullet @@ -533,12 +540,11 @@ public sealed class BSPrim : BSPhysObject else { // Not a Bullet static object - BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); // A dynamic object has mass - BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, OMV.Vector3.Zero); - // The shape is interesting and has mass and a center of gravity IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr); - BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass, OMV.Vector3.Zero); + OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass); + BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia); // Inertia is based on our new mass BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); // Force activation of the object so Bullet will act on it. @@ -546,8 +552,31 @@ public sealed class BSPrim : BSPhysObject } } - private void MakeSolid() + // "Making solid" means that other object will not pass through this object. + private void MakeSolid(bool makeSolid) { + if (makeSolid) + { + // Easy in Bullet -- just remove the object flag that controls collision response + m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + } + else + { + m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + } + } + + // Turn on or off the flag controlling whether collision events are returned to the simulator. + private void EnableCollisions(bool wantsCollisionEvents) + { + if (wantsCollisionEvents) + { + m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + } + else + { + m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + } } // prims don't fly @@ -607,7 +636,7 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity); }); } } @@ -624,7 +653,10 @@ public sealed class BSPrim : BSPhysObject _scene.TaintedObject("BSPrim.setBuoyancy", delegate() { DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); + // Buoyancy is faked by changing the gravity applied to the object + float grav = Scene.Params.gravity * (1f - _buoyancy); + BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav)); + // BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); }); } } @@ -686,8 +718,8 @@ public sealed class BSPrim : BSPhysObject } m_accumulatedForces.Clear(); } - DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); - // For unknown reason, "ApplyCentralForce" is really additive. + 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); }); } @@ -1030,29 +1062,36 @@ public sealed class BSPrim : BSPhysObject // Returns 'true' if the geometry was rebuilt private bool CreateGeom(bool forceRebuild) { - // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. bool ret = false; - if (!_scene.NeedsMeshing(_pbs)) + bool haveShape = false; + + // If the prim attributes are simple, this could be a simple Bullet native shape + if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim) + || (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0 + && _pbs.ProfileHollow == 0 + && _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0 + && _pbs.PathBegin == 0 && _pbs.PathEnd == 0 + && _pbs.PathTaperX == 0 && _pbs.PathTaperY == 0 + && _pbs.PathScaleX == 100 && _pbs.PathScaleY == 100 + && _pbs.PathShearX == 0 && _pbs.PathShearY == 0) ) { if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) { - // if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) - // { - // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); - if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) - { - DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); - _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; - // Bullet native objects are scaled by the Bullet engine so pass the size in - _scale = _size; - // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? - ret = true; - } - // } + haveShape = true; + if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) + { + DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); + _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; + // Bullet native objects are scaled by the Bullet engine so pass the size in + _scale = _size; + // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? + ret = true; + } } else { // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); + haveShape = true; if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) { DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); @@ -1063,16 +1102,16 @@ public sealed class BSPrim : BSPhysObject } } } - else + // If a simple shape isn't happening, create a mesh and possibly a hull + if (!haveShape) { if (IsPhysical) { if (forceRebuild || _hullKey == 0) { // physical objects require a hull for interaction. - // This will create the mesh if it doesn't already exist - CreateGeomHull(); - ret = true; + // This also creates the mesh if it doesn't already exist + ret = CreateGeomHull(); } } else @@ -1080,8 +1119,7 @@ public sealed class BSPrim : BSPhysObject if (forceRebuild || _meshKey == 0) { // Static (non-physical) objects only need a mesh for bumping into - CreateGeomMesh(); - ret = true; + ret = CreateGeomMesh(); } } } @@ -1089,7 +1127,8 @@ public sealed class BSPrim : BSPhysObject } // No locking here because this is done when we know physics is not simulating - private void CreateGeomMesh() + // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). + private bool CreateGeomMesh() { // level of detail based on size and type of the object float lod = _scene.MeshLOD; @@ -1103,7 +1142,7 @@ public sealed class BSPrim : BSPhysObject // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); // if this new shape is the same as last time, don't recreate the mesh - if (_meshKey == newMeshKey) return; + if (_meshKey == newMeshKey) return false; DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); // Since we're recreating new, get rid of any previously generated shape @@ -1140,19 +1179,19 @@ public sealed class BSPrim : BSPhysObject _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); - DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); - return; + return true; } // No locking here because this is done when we know physics is not simulating - private void CreateGeomHull() + // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). + private bool CreateGeomHull() { float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod); // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey); // if the hull hasn't changed, don't rebuild it - if (newHullKey == _hullKey) return; + if (newHullKey == _hullKey) return false; DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); @@ -1255,7 +1294,7 @@ public sealed class BSPrim : BSPhysObject // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); - return; + return true; } // Callback from convex hull creater with a newly created hull. @@ -1268,20 +1307,12 @@ public sealed class BSPrim : BSPhysObject private void VerifyCorrectPhysicalShape() { - if (IsStatic) - { - // if static, we don't need a hull so, if there is one, rebuild without it - if (_hullKey != 0) - { - RecreateGeomAndObject(); - } - } - else + if (!IsStatic) { // if not static, it will need a hull to efficiently collide with things if (_hullKey == 0) { - RecreateGeomAndObject(); + CreateGeomAndObject(false); } } @@ -1300,8 +1331,9 @@ public sealed class BSPrim : BSPhysObject // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); - // the CreateObject() may have recreated the rigid body. Make sure we have the latest. + // the CreateObject() may have recreated the rigid body. Make sure we have the latest address. BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); + BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr)); return ret; } @@ -1325,15 +1357,20 @@ public sealed class BSPrim : BSPhysObject shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; } - // Rebuild the geometry and object. // This is called when the shape changes so we need to recreate the mesh/hull. // No locking here because this is done when the physics engine is not simulating - private void RecreateGeomAndObject() + private void CreateGeomAndObject(bool forceRebuild) { - // m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID); - if (CreateGeom(true)) + // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, _localID, forceRebuild); + // Create the geometry that will make up the object + if (CreateGeom(forceRebuild)) + { + // Create the object and place it into the world CreateObject(); + // Make sure the properties are set on the new object + UpdatePhysicalParameters(); + } return; } @@ -1430,9 +1467,10 @@ public sealed class BSPrim : BSPhysObject // I've collided with something // Called at taint time from within the Step() function CollisionEventUpdate collisionCollection; - public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); + bool ret = false; // The following lines make IsColliding() and IsCollidingGround() work _collidingStep = _scene.SimulationStep; @@ -1446,7 +1484,7 @@ public sealed class BSPrim : BSPhysObject // prims in the same linkset cannot collide with each other if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) { - return; + return ret; } // if someone has subscribed for collision events.... @@ -1459,8 +1497,10 @@ public sealed class BSPrim : BSPhysObject if (collisionCollection == null) collisionCollection = new CollisionEventUpdate(); collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + ret = true; } } + return ret; } // The scene is telling us it's time to pass our collected collisions into the simulator diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 4a468af..eea899f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -79,7 +79,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters private HashSet m_objectsWithCollisions = new HashSet(); // Following is a kludge and can be removed when avatar animation updating is // moved to a better place. - private HashSet m_avatarsWithCollisions = new HashSet(); + private HashSet m_avatarsWithCollisions = new HashSet(); // List of all the objects that have vehicle properties and should be called // to update each physics step. @@ -132,8 +132,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters private EntityProperties[] m_updateArray; private GCHandle m_updateArrayPinnedHandle; - private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed - private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes + public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed + public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes public float PID_D { get; private set; } // derivative public float PID_P { get; private set; } // proportional @@ -153,6 +153,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters { get { return new Vector3(0f, 0f, Params.gravity); } } + // Just the Z value of the gravity + public float DefaultGravityZ + { + get { return Params.gravity; } + } public float MaximumObjectMass { get; private set; } @@ -171,8 +176,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters callback = c; } } + private Object _taintLock = new Object(); // lock for using the next object private List _taintedObjects; - private Object _taintLock = new Object(); // A pointer to an instance if this structure is passed to the C++ code // Used to pass basic configuration values to the unmanaged code. @@ -478,6 +483,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // Some of the prims operate with special vehicle properties ProcessVehicles(timeStep); + numTaints += _taintedObjects.Count; ProcessTaints(); // the vehicles might have added taints // step the physical world one interval @@ -506,6 +512,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters // Get a value for 'now' so all the collision and update routines don't have to get their own SimulationNowTime = Util.EnvironmentTickCount(); + // This is a kludge to get avatar movement updates. + // ODE sends collisions for avatars even if there are have been no collisions. This updates + // avatar animations and stuff. + // If you fix avatar animation updates, remove this overhead and let collisions happen. + m_objectsWithCollisions = new HashSet(m_avatarsWithCollisions); + // If there were collisions, process them by sending the event to the prim. // Collisions must be processed before updates. if (collidersCount > 0) @@ -527,13 +539,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters bsp.SendCollisions(); m_objectsWithCollisions.Clear(); - // This is a kludge to get avatar movement updated. - // ODE sends collisions even if there are none and this is used to update - // avatar animations and stuff. - foreach (BSPhysObject bpo in m_avatarsWithCollisions) - bpo.SendCollisions(); - // m_avatarsWithCollisions.Clear(); - // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) { @@ -544,7 +549,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (PhysObjects.TryGetValue(entprop.ID, out pobj)) { pobj.UpdateProperties(entprop); - continue; } } } @@ -600,8 +604,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); - collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration); - m_objectsWithCollisions.Add(collider); + if (collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration)) + { + // If a collision was posted, remember to send it to the simulator + m_objectsWithCollisions.Add(collider); + } return; } @@ -619,9 +626,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters public override void SetWaterLevel(float baseheight) { m_waterLevel = baseheight; - // TODO: pass to physics engine so things will float? } - public float GetWaterLevel() + // Someday.... + public float GetWaterLevelAtXYZ(Vector3 loc) { return m_waterLevel; } @@ -672,7 +679,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // int iPropertiesNotSupportedDefault = 0; - if (pbs.SculptEntry && !_meshSculptedPrim) + if (pbs.SculptEntry && !ShouldMeshSculptedPrim) { // Render sculpties as boxes return false; @@ -680,7 +687,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet // can use an internal representation for the prim - if (!_forceSimplePrimMeshing) + if (!ShouldForceSimplePrimMeshing) { if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 @@ -782,7 +789,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (!m_initialized) return; lock (_taintLock) + { _taintedObjects.Add(new TaintCallbackEntry(ident, callback)); + } + return; } @@ -919,14 +929,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters { new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s._meshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s._meshSculptedPrim); }, - (s,p,l,v) => { s._meshSculptedPrim = s.BoolNumeric(v); } ), + (s,cf,p,v) => { s.ShouldMeshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); }, + (s) => { return s.NumericBool(s.ShouldMeshSculptedPrim); }, + (s,p,l,v) => { s.ShouldMeshSculptedPrim = s.BoolNumeric(v); } ), new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s._forceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, - (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), + (s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, + (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); }, + (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ), new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 8f, @@ -1162,8 +1172,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, (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=none, 1=all. Default=0", - 0.0f, + new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", + 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; } ), @@ -1172,6 +1182,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters (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; } ), + new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", + 40, + (s,cf,p,v) => { s.m_params[0].linkConstraintSolverIterations = cf.GetFloat(p, v); }, + (s) => { return s.m_params[0].linkConstraintSolverIterations; }, + (s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ), new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)", 0f, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 47d7199..d48462e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -154,27 +154,31 @@ public class BSTerrainManager // The simulator wants to set a new heightmap for the terrain. public void SetTerrain(float[] heightMap) { - if (m_worldOffset != Vector3.Zero && m_parentScene != null) + float[] localHeightMap = heightMap; + m_physicsScene.TaintedObject("TerrainManager.SetTerrain", delegate() { - // If a child of a mega-region, we shouldn't have any terrain allocated for us - ReleaseGroundPlaneAndTerrain(); - // If doing the mega-prim stuff and we are the child of the zero region, - // the terrain is added to our parent - if (m_parentScene is BSScene) + if (m_worldOffset != Vector3.Zero && m_parentScene != null) { - DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", - BSScene.DetailLogZero, m_worldOffset, m_worldMax); - ((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID, - heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false); + // If a child of a mega-region, we shouldn't have any terrain allocated for us + ReleaseGroundPlaneAndTerrain(); + // If doing the mega-prim stuff and we are the child of the zero region, + // the terrain is added to our parent + if (m_parentScene is BSScene) + { + DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", + BSScene.DetailLogZero, m_worldOffset, m_worldMax); + ((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID, + localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true); + } } - } - else - { - // If not doing the mega-prim thing, just change the terrain - DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); + else + { + // If not doing the mega-prim thing, just change the terrain + DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); - UpdateOrCreateTerrain(BSScene.TERRAIN_ID, heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false); - } + UpdateOrCreateTerrain(BSScene.TERRAIN_ID, localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true); + } + }); } // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain @@ -319,6 +323,8 @@ public class BSTerrainManager // Make sure the new shape is processed. BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true); + + m_terrainModified = true; }; // There is the option to do the changes now (we're already in 'taint time'), or @@ -357,6 +363,8 @@ public class BSTerrainManager m_heightMaps.Add(terrainRegionBase, mapInfo); // Build the terrain 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. @@ -383,7 +391,7 @@ public class BSTerrainManager private float lastHeightTX = 999999f; private float lastHeightTY = 999999f; private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; - public float GetTerrainHeightAtXY(float tX, float tY) + private float GetTerrainHeightAtXY(float tX, float tY) { // You'd be surprized at the number of times this routine is called // with the same parameters as last time. @@ -403,11 +411,18 @@ public class BSTerrainManager { float regionX = tX - offsetX; float regionY = tY - offsetY; - if (regionX >= mapInfo.sizeX || regionX < 0f) regionX = 0; - if (regionY >= mapInfo.sizeY || regionY < 0f) regionY = 0; int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX; - ret = mapInfo.heightMap[mapIndex]; - m_terrainModified = false; + try + { + ret = mapInfo.heightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, x={2}, y={3}", + LogHeader, terrainBaseXY, regionX, regionY); + ret = HEIGHT_GETHEIGHT_RET; + } // DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}", // BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret); } @@ -416,6 +431,7 @@ public class BSTerrainManager m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", LogHeader, m_physicsScene.RegionName, tX, tY); } + m_terrainModified = false; lastHeight = ret; return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index e579cf2..043423e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -213,6 +213,7 @@ public struct ConfigurationParameters public float linkConstraintTransMotorMaxForce; public float linkConstraintERP; public float linkConstraintCFM; + public float linkConstraintSolverIterations; public const float numericTrue = 1f; public const float numericFalse = 0f; @@ -395,23 +396,6 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool CreateObject(uint worldID, ShapeData shapeData); -/* Remove old functionality -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void AddConstraint(uint worldID, uint id1, uint id2, - Vector3 frame1, Quaternion frame1rot, - Vector3 frame2, Quaternion frame2rot, - Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveConstraintByID(uint worldID, uint id1); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); - */ - [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern Vector3 GetObjectPosition(uint WorldID, uint id); @@ -545,6 +529,15 @@ public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +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); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -1010,7 +1003,7 @@ public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale); public static extern Vector3 GetLocalScaling2(IntPtr shape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void CalculateLocalInertia2(IntPtr shape, float mass, Vector3 inertia); +public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern int GetShapeType2(IntPtr shape); -- cgit v1.1 From c0fec70b1ad3047b8e543558a6aaee2916bd7b3f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Sep 2012 10:10:29 -0700 Subject: BulletSim: Add 'IsNativeShape2' call --- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 043423e..087c61b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -523,10 +523,7 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, float shapeType, float collisionMargin, Vector3 scale); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot); +public static extern bool IsNativeShape2(IntPtr shape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateCompoundShape2(IntPtr sim); @@ -541,6 +538,12 @@ public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr re public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -- cgit v1.1 From d86cbe637943acde05528d0bce6dc61a77257cc0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Sep 2012 10:11:25 -0700 Subject: BulletSim: remove unused NeedsMeshing() code from BSScene. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 116 ------------------------ 1 file changed, 116 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index eea899f..9c958d5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -56,7 +56,6 @@ using OpenMetaverse; // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect // Implement LockAngularMotion // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) -// Does NeedsMeshing() really need to exclude all the different shapes? // Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet. // Add PID movement operations. What does ScenePresence.MoveToTarget do? // Check terrain size. 128 or 127? @@ -666,121 +665,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters public override bool IsThreaded { get { return false; } } - /// - /// Routine to figure out if we need to mesh this prim with our mesher - /// - /// - /// true if the prim needs meshing - public bool NeedsMeshing(PrimitiveBaseShape pbs) - { - // most of this is redundant now as the mesher will return null if it cant mesh a prim - // but we still need to check for sculptie meshing being enabled so this is the most - // convenient place to do it for now... - - // int iPropertiesNotSupportedDefault = 0; - - if (pbs.SculptEntry && !ShouldMeshSculptedPrim) - { - // Render sculpties as boxes - return false; - } - - // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet - // can use an internal representation for the prim - if (!ShouldForceSimplePrimMeshing) - { - if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) - || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 - && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) - { - - if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 - && pbs.ProfileHollow == 0 - && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 - && pbs.PathBegin == 0 && pbs.PathEnd == 0 - && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 - && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 - && pbs.PathShearX == 0 && pbs.PathShearY == 0) - { - return false; - } - } - } - - /* TODO: verify that the mesher will now do all these shapes - if (pbs.ProfileHollow != 0) - iPropertiesNotSupportedDefault++; - - if ((pbs.PathBegin != 0) || pbs.PathEnd != 0) - iPropertiesNotSupportedDefault++; - - if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) - iPropertiesNotSupportedDefault++; - - if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) - iPropertiesNotSupportedDefault++; - - if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) - iPropertiesNotSupportedDefault++; - - if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) - iPropertiesNotSupportedDefault++; - - if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) - iPropertiesNotSupportedDefault++; - - if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) - iPropertiesNotSupportedDefault++; - - if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1) - iPropertiesNotSupportedDefault++; - - // test for torus - if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square) - { - if (pbs.PathCurve == (byte)Extrusion.Curve1) - { - iPropertiesNotSupportedDefault++; - } - } - else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - { - if (pbs.PathCurve == (byte)Extrusion.Straight) - { - iPropertiesNotSupportedDefault++; - } - // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits - else if (pbs.PathCurve == (byte)Extrusion.Curve1) - { - iPropertiesNotSupportedDefault++; - } - } - else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) - { - if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2) - { - iPropertiesNotSupportedDefault++; - } - } - else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) - { - if (pbs.PathCurve == (byte)Extrusion.Straight) - { - iPropertiesNotSupportedDefault++; - } - else if (pbs.PathCurve == (byte)Extrusion.Curve1) - { - iPropertiesNotSupportedDefault++; - } - } - if (iPropertiesNotSupportedDefault == 0) - { - return false; - } - */ - return true; - } - // 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. -- cgit v1.1 From 7c347f4c5c966848669b979b367e1bc3912621d5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Sep 2012 10:11:39 -0700 Subject: BulletSim: Add calls to linkset class when object going static or dynamic. Reset center of mass on an object when going dynamic. --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 20 ++++++++++++++++++-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 20 ++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index dc1de6c..3d73887 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -202,6 +202,24 @@ public class BSLinkset return com; } + // The object is going dynamic (physical). Do any setup necessary + // for a dynamic linkset. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public bool MakeDynamic(BSPhysObject child) + { + 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. + // Called at taint-time! + public bool MakeStatic(BSPhysObject child) + { + return false; + } + // When physical properties are changed the linkset needs to recalculate // its internal properties. public void Refresh(BSPhysObject requestor) @@ -255,13 +273,11 @@ public class BSLinkset if (!somethingMissing) { // The root prim takes on the weight of the whole linkset - /* OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(LinksetRoot.BSShape.Ptr, linksetMass); BulletSimAPI.SetMassProps2(LinksetRoot.BSBody.Ptr, linksetMass, inertia); OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); BulletSimAPI.UpdateInertiaTensor2(LinksetRoot.BSBody.Ptr); - */ } } return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 481a8db..04b7be5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -530,10 +530,14 @@ public sealed class BSPrim : BSPhysObject m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement BulletSimAPI.ClearAllForces2(BSBody.Ptr); + // Center of mass is at the center of the object + 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); + // There can be special things needed for implementing linksets + Linkset.MakeStatic(this); // The activation state is 'sleeping' so Bullet will not try to act on it BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING); } @@ -543,10 +547,12 @@ public sealed class BSPrim : BSPhysObject m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); // A dynamic object has mass IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr); - OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass); + OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass); BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia); // Inertia is based on our new mass BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); + // There can be special things needed for implementing linksets + Linkset.MakeDynamic(this); // Force activation of the object so Bullet will act on it. BulletSimAPI.Activate2(BSBody.Ptr, true); } @@ -1055,11 +1061,12 @@ public sealed class BSPrim : BSPhysObject }// end CalculateMass #endregion Mass Calculation - // Create the geometry information in Bullet for later use - // The objects needs a hull if it's physical otherwise a mesh is enough - // No locking here because this is done when we know physics is not simulating - // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used - // Returns 'true' if the geometry was rebuilt + // Create the geometry information in Bullet for later use. + // The objects needs a hull if it's physical otherwise a mesh is enough. + // No locking here because this is done when we know physics is not simulating. + // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used. + // Returns 'true' if the geometry was rebuilt. + // Called at taint-time! private bool CreateGeom(bool forceRebuild) { bool ret = false; @@ -1128,6 +1135,7 @@ public sealed class BSPrim : BSPhysObject // No locking here because this is done when we know physics is not simulating // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). + // Called at taint-time! private bool CreateGeomMesh() { // level of detail based on size and type of the object -- cgit v1.1 From f0a098924e8a3f64692de5d3326bfbdfb2b208a2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Sep 2012 13:51:28 -0700 Subject: BulletSim: set all linkset objects center of mass to the whole linkset's center of mass --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 3d73887..7e784eb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -204,11 +204,14 @@ public class BSLinkset // 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 bool MakeDynamic(BSPhysObject child) { - return false; + bool ret = false; + return ret; } // The object is going static (non-physical). Do any setup necessary @@ -217,6 +220,7 @@ public class BSLinkset // Called at taint-time! public bool MakeStatic(BSPhysObject child) { + // What is done for each object in BSPrim is what we want. return false; } @@ -269,15 +273,24 @@ public class BSLinkset } } - // If the whole linkset is not here, doesn't make sense to recompute the root prim now. + // If the whole linkset is not here, doesn't make sense to recompute linkset wide values if (!somethingMissing) { + // 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); + foreach (BSPhysObject child in m_children) + { + BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); + } + /* // The root prim takes on the weight of the whole linkset OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(LinksetRoot.BSShape.Ptr, linksetMass); BulletSimAPI.SetMassProps2(LinksetRoot.BSBody.Ptr, linksetMass, inertia); OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); BulletSimAPI.UpdateInertiaTensor2(LinksetRoot.BSBody.Ptr); + */ } } return; -- cgit v1.1 From 6632eb7c051e2638ea1c58c2876e7d6825398556 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Sep 2012 13:51:42 -0700 Subject: BulletSim: Remove calculation and passing of unused collied object type. Fix collision code to properly sense mega-region children regions as terrain. When setting an object physical, reset all the physical properties (friction, ...). --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 8 +++---- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 28 +++++++++++++++++----- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 26 ++++++++------------ 4 files changed, 36 insertions(+), 28 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index a9b1365..526dbad 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -529,22 +529,20 @@ public class BSCharacter : BSPhysObject // The collision, if it should be reported to the character, is placed in a collection // that will later be sent to the simulator when SendCollisions() is called. CollisionEventUpdate collisionCollection = null; - public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) + public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) { - // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); - bool ret = false; // The following makes IsColliding() and IsCollidingGround() work _collidingStep = Scene.SimulationStep; - if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) + if (collidingWith <= Scene.TerrainManager.HighestTerrainID) { _collidingGroundStep = Scene.SimulationStep; } // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); // throttle collisions to the rate specified in the subscription - if (_subscribedEventsMs != 0) { + if (SubscribedEvents()) { int nowTime = Scene.SimulationNowTime; if (nowTime >= _nextCollisionOkTime) { _nextCollisionOkTime = nowTime + _subscribedEventsMs; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 969c53e..3fe71e1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -41,7 +41,7 @@ public abstract class BSPhysObject : PhysicsActor { public abstract BSLinkset Linkset { get; set; } - public abstract bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, + public abstract bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); public abstract void SendCollisions(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 04b7be5..6827be0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -545,14 +545,31 @@ public sealed class BSPrim : BSPhysObject { // Not a Bullet static object m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Set various physical properties so internal things will get computed correctly as they are set + BulletSimAPI.SetFriction2(BSBody.Ptr, Scene.Params.defaultFriction); + BulletSimAPI.SetRestitution2(BSBody.Ptr, Scene.Params.defaultRestitution); + // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 + BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); + BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); + // A dynamic object has mass IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr); OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass); BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia); // Inertia is based on our new mass BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); + + // Various values for simulation limits + BulletSimAPI.SetDamping2(BSBody.Ptr, Scene.Params.linearDamping, Scene.Params.angularDamping); + BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, Scene.Params.deactivationTime); + BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, Scene.Params.linearSleepingThreshold, Scene.Params.angularSleepingThreshold); + BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, Scene.Params.contactProcessingThreshold); + // There can be special things needed for implementing linksets Linkset.MakeDynamic(this); + // Force activation of the object so Bullet will act on it. BulletSimAPI.Activate2(BSBody.Ptr, true); } @@ -1475,16 +1492,15 @@ public sealed class BSPrim : BSPhysObject // I've collided with something // Called at taint time from within the Step() function CollisionEventUpdate collisionCollection; - public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { - // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); bool ret = false; // The following lines make IsColliding() and IsCollidingGround() work - _collidingStep = _scene.SimulationStep; - if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) + _collidingStep = Scene.SimulationStep; + if (collidingWith <= Scene.TerrainManager.HighestTerrainID) { - _collidingGroundStep = _scene.SimulationStep; + _collidingGroundStep = Scene.SimulationStep; } // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); @@ -1498,7 +1514,7 @@ public sealed class BSPrim : BSPhysObject // if someone has subscribed for collision events.... if (SubscribedEvents()) { // throttle the collisions to the number of milliseconds specified in the subscription - int nowTime = _scene.SimulationNowTime; + int nowTime = Scene.SimulationNowTime; if (nowTime >= _nextCollisionOkTime) { _nextCollisionOkTime = nowTime + _subscribedEventsMs; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 9c958d5..c38867f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -583,27 +583,21 @@ public class BSScene : PhysicsScene, IPhysicsParameters return; // don't send collisions to the terrain } - BSPhysObject collider = PhysObjects[localID]; - // TODO: as of this code, terrain was not in the physical object list. - // When BSTerrain is created and it will be in the list, we can remove - // the possibility that it's not there and just fetch the collidee. - BSPhysObject collidee = null; - - ActorTypes type = ActorTypes.Prim; - if (collidingWith <= TerrainManager.HighestTerrainID) + BSPhysObject collider; + if (!PhysObjects.TryGetValue(localID, out collider)) { - type = ActorTypes.Ground; - } - else - { - collidee = PhysObjects[collidingWith]; - if (collidee is BSCharacter) - type = ActorTypes.Agent; + // If the object that is colliding cannot be found, just ignore the collision. + return; } + // The terrain is not in the physical object list so 'collidee' + // can be null when Collide() is called. + BSPhysObject collidee = null; + PhysObjects.TryGetValue(collidingWith, out collidee); + // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); - if (collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration)) + if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) { // If a collision was posted, remember to send it to the simulator m_objectsWithCollisions.Add(collider); -- cgit v1.1 From dcb94b8a242dff0f3a33f084565af49d6582f663 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 14 Sep 2012 11:11:43 -0700 Subject: BulletSim: remove timeStep parameter from calls for vehicle parameter setting. There is no reason these should be using the simulation time interval for parameter calculation. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 9 +++------ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 098fea7..5f62b12 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -131,7 +131,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_type = Vehicle.TYPE_NONE; } - internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) + internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); switch (pParam) @@ -230,7 +230,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } }//end ProcessFloatVehicleParam - internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) + internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) { VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); switch (pParam) @@ -299,7 +299,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } }//end ProcessVehicleFlags - internal void ProcessTypeChange(Vehicle pType, float stepSize) + internal void ProcessTypeChange(Vehicle pType) { VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); // Set Defaults For Type @@ -537,9 +537,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Add the various forces into m_dir which will be our new direction vector (velocity) // add Gravity and Buoyancy - // KF: So far I have found no good method to combine a script-requested - // .Z velocity and gravity. Therefore only 0g will used script-requested - // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. // There is some gravity, make a gravity force vector that is applied after object velocity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy)); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 6827be0..d97231c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -346,7 +346,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, Scene.LastSimulatedTimestep); + _vehicle.ProcessTypeChange(type); // Tell the scene about the vehicle so it will get processing each frame. _scene.VehicleInSceneTypeChanged(this, type); }); @@ -356,14 +356,14 @@ public sealed class BSPrim : BSPhysObject { _scene.TaintedObject("BSPrim.VehicleFloatParam", delegate() { - _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); + _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); }); } public override void VehicleVectorParam(int param, OMV.Vector3 value) { _scene.TaintedObject("BSPrim.VehicleVectorParam", delegate() { - _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); + _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); }); } public override void VehicleRotationParam(int param, OMV.Quaternion rotation) -- cgit v1.1 From f35bd6eb7d5b0eb1a6d385f5f1d0147acfc3c8ef Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 14 Sep 2012 11:12:23 -0700 Subject: BulletSim: another attempt at computing physics FPS correctly. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 29 +++++-------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index c38867f..52997dd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -110,11 +110,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters private long m_simulationStep = 0; public long SimulationStep { get { return m_simulationStep; } } - // The length of the last timestep we were asked to simulate. - // This is used by the vehicle code. Since the vehicle code is called - // once per simulation step, its constants need to be scaled by this. - public float LastSimulatedTimestep { get; private set; } - // A value of the time now so all the collision and update routines do not have to get their own // Set to 'now' just before all the prims and actors are called for collisions and updates public int SimulationNowTime { get; private set; } @@ -469,12 +464,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters int collidersCount = 0; IntPtr collidersPtr; - LastSimulatedTimestep = timeStep; - // prevent simulation until we've been initialized - if (!m_initialized) return 10.0f; - - int simulateStartTime = Util.EnvironmentTickCount(); + if (!m_initialized) return 5.0f; // update the prim states while we know the physics engine is not busy int numTaints = _taintedObjects.Count; @@ -514,7 +505,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // This is a kludge to get avatar movement updates. // ODE sends collisions for avatars even if there are have been no collisions. This updates // avatar animations and stuff. - // If you fix avatar animation updates, remove this overhead and let collisions happen. + // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. m_objectsWithCollisions = new HashSet(m_avatarsWithCollisions); // If there were collisions, process them by sending the event to the prim. @@ -561,18 +552,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters } } - // this is a waste since the outside routine also calcuates the physics simulation - // period. TODO: There should be a way of computing physics frames from simulator computation. - // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); - // return (timeStep * (float)simulateTotalTime); - - // TODO: FIX THIS: fps calculation possibly wrong. - // This calculation says 1/timeStep is the ideal frame rate. Any time added to - // that by the physics simulation gives a slower frame rate. - long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime); - if (totalSimulationTime >= timeStep) - return 0; - return 1f / (timeStep + totalSimulationTime); + // The physics engine returns the number of milliseconds it simulated this call. + // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. + // Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS. + return numSubSteps * m_fixedTimeStep; } // Something has collided -- cgit v1.1 From 1826b2b18e8d82a91ca34787e17cf4ef0d1f46a6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 14 Sep 2012 11:13:05 -0700 Subject: BulletSim: add the debugging routine DumpRigidBody2() to API2. --- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 087c61b..9221cdb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -558,9 +558,6 @@ public static extern void DestroyObject2(IntPtr sim, IntPtr obj); // ===================================================================================== // Terrain creation and helper routines [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpMapInfo(IntPtr sim, IntPtr manInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); @@ -1023,6 +1020,12 @@ public static extern void SetCollisionFilterMask(IntPtr shape, uint filter, uint // ===================================================================================== // Debugging [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DumpPhysicsStatistics2(IntPtr sim); } -- cgit v1.1 From c77be802d2879c0504438905359c1b865a92d3a1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 15 Sep 2012 15:23:54 -0700 Subject: BulletSim: some debugging prints in BSPrim for tracking changes in linkset children. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d97231c..26a581f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1476,12 +1476,14 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); + // BulletSimAPI.DumpRigidBody2(Scene.World.Ptr, BSBody.Ptr); + base.RequestPhysicsterseUpdate(); } /* else { - // For debugging, we also report the movement of children + // For debugging, we can also report the movement of children DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); -- cgit v1.1 From b602b476adafe8e6eab9ec257db029a3d05db224 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 15 Sep 2012 15:36:13 -0700 Subject: BulletSim: update DLLs and SOs and remove some debugging code. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5f62b12..61006f0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -475,7 +475,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin frcount = 0; MoveLinear(pTimestep); - // MoveAngular(pTimestep); + MoveAngular(pTimestep); LimitRotation(pTimestep); // remember the position so next step we can limit absolute movement effects -- cgit v1.1