From 98168edc29c7c761121e453d82bf1fab52814b58 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 11:06:49 -0800 Subject: BulletSim: remove double application of buoyancy. Centralize computation of buoyancy. Add motor angular debugging controls. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 42 +++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 23 ++------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 + .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 58 ++++++++++++---------- 4 files changed, 59 insertions(+), 65 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c34c05a..47f2759 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -124,6 +124,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin static readonly float PIOverFour = ((float)Math.PI) / 4f; static readonly float PIOverTwo = ((float)Math.PI) / 2f; + // For debugging, flags to turn on and off individual corrections. + private bool enableAngularVerticalAttraction = true; + private bool enableAngularDeflection = true; + private bool enableAngularBanking = true; + public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -575,11 +580,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); - Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); + // Set the gravity for the vehicle depending on the buoyancy + // TODO: what should be done if prim and vehicle buoyancy differ? + Vector3 grav = Prim.ComputeGravity(m_VehicleBuoyancy); PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); - VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", - Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); + VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", + Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping, grav); } else { @@ -858,12 +865,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin linearMotorContribution *= VehicleOrientation; // All the contributions after this are world relative (mostly Z modifications) - // ================================================================== - // Buoyancy: force to overcome gravity. - // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. - Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); Vector3 hoverContribution = ComputeLinearHover(pTimestep); @@ -873,12 +874,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); // ================================================================== + // Select between velocities and forces. Forces will happen over time and + // will take into account inertia, collisions, etc. Velocities are + // raw updates to the velocity of the vehicle. Vector3 newVelocity = linearMotorContribution + terrainHeightContribution + hoverContribution + limitMotorUpContribution; - Vector3 newForce = buoyancyContribution; + Vector3 newForce = Vector3.Zero; // If not changing some axis, reduce out velocity if ((m_flags & (VehicleFlag.NO_X)) != 0) @@ -902,6 +906,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Stuff new linear velocity into the vehicle. // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. + // Also not scaled by mass since this is a super-physical setting of velocity. VehicleVelocity = newVelocity; // Other linear forces are applied as forces. @@ -911,13 +916,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleAddForce(totalDownForce); } - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", - Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); - VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", + VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},totDown={5},isColl={6},newVel={7}", Prim.LocalID, - linearMotorContribution, terrainHeightContribution, hoverContribution, - limitMotorUpContribution, buoyancyContribution - ); + linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution, + totalDownForce, Prim.IsColliding, newVelocity ); } // end MoveLinear() @@ -1088,6 +1090,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // for preventing ground vehicles with large linear deflection, like bumper cars, // from climbing their linear deflection into the sky. // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + // TODO: This is here because this is where ODE put it but documentation says it + // is a linear effect. Where should this check go? if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { angularMotorContribution.X = 0f; @@ -1179,7 +1183,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 ret = Vector3.Zero; // If vertical attaction timescale is reasonable - if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) + if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1230,7 +1234,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // this creates an over-correction and then wabbling as the target is overshot. // TODO: rethink how the different correction computations inter-relate. - if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) + if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) { // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; @@ -1303,7 +1307,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 ret = Vector3.Zero; - if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) + if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. // As the vehicle rolls to the right or left, the Y value will increase from diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8fd054f..50ba343 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -410,7 +410,7 @@ public sealed class BSPrim : BSPhysObject } else { - OMV.Vector3 grav = ComputeGravity(); + OMV.Vector3 grav = ComputeGravity(Buoyancy); if (inWorld) { @@ -445,12 +445,12 @@ public sealed class BSPrim : BSPhysObject } // Return what gravity should be set to this very moment - private OMV.Vector3 ComputeGravity() + public OMV.Vector3 ComputeGravity(float buoyancy) { OMV.Vector3 ret = PhysicsScene.DefaultGravity; if (!IsStatic) - ret *= (1f - Buoyancy); + ret *= (1f - buoyancy); return ret; } @@ -1561,21 +1561,6 @@ public sealed class BSPrim : BSPhysObject // The physics engine says that properties have updated. Update same and inform // the world that things have changed. - // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() - enum UpdatedProperties { - Position = 1 << 0, - Rotation = 1 << 1, - Velocity = 1 << 2, - Acceleration = 1 << 3, - RotationalVel = 1 << 4 - } - - const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; - const float ACCELERATION_TOLERANCE = 0.01f; - const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; - public override void UpdateProperties(EntityProperties entprop) { // Updates only for individual prims and for the root object of a linkset. @@ -1588,7 +1573,7 @@ public sealed class BSPrim : BSPhysObject entprop.RotationalVelocity = OMV.Vector3.Zero; } - // Assign directly to the local variables so the normal set action does not happen + // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7017194..4a6cebd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -486,6 +486,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessTaints(); // Some of the physical objects requre individual, pre-step calls + // (vehicles and avatar movement, in particular) TriggerPreStepEvent(timeStep); // the prestep actions might have added taints diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 29bd4e4..1540dbb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,12 +1,17 @@ CURRENT PRIORITIES ================================================= +Nebadon vehicles turning funny in arena +limitMotorUp calibration (more down?) +Vehicle angular vertical attraction +Vehicle angular deflection + Preferred orientation angular correction fix +vehicle angular banking Avatars walking up stairs (HALF DONE) + Radius of the capsule affects ability to climb edges. Vehicle movement on terrain smoothness -limitMotorUp calibration (more down?) -Preferred orientation angular correction fix Surfboard go wonky when turning Angular motor direction is global coordinates rather than local coordinates? -Boats float low in the water +Boats float low in the water (DONE) Avatar movement flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) walking up stairs is not calibrated correctly (stairs out of Kepler cabin) @@ -33,19 +38,15 @@ CRASHES VEHICLES TODO LIST: ================================================= -Angular motor direction is global coordinates rather than local coordinates Border crossing with linked vehicle causes crash Vehicles (Move smoothly) -Add vehicle collisions so IsColliding is properly reported. - Needed for banking, limitMotorUp, movementLimiting, ... -VehicleAddForce is not scaled by the simulation step but it is only - applied for one step. Should it be scaled? Some vehicles should not be able to turn if no speed or off ground. Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. Implement referenceFrame for all the motion routines. +For limitMotorUp, use raycast down to find if vehicle is in the air. Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. Verify llGetVel() is returning a smooth and good value for vehicle movement. @@ -54,14 +55,13 @@ Implement function efficiency for lineaar and angular motion. After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) -For limitMotorUp, use raycast down to find if vehicle is in the air. Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). A kludge that isn't fixing the real problem of Bullet adding extra motion. Incorporate inter-relationship of angular corrections. For instance, angularDeflection and angularMotorUp will compute same X or Y correction. When added together creates over-correction and over-shoot and wabbling. -BULLETSIM TODO LIST: +GENERAL TODO LIST: ================================================= Implement an avatar mesh shape. The Bullet capsule is way too limited. Consider just hand creating a vertex/index array in a new BSShapeAvatar. @@ -121,11 +121,9 @@ LinksetCompound: when one of the children changes orientation (like tires Verify/think through scripts in children of linksets. What do they reference and return when getting position, velocity, ... Confirm constraint linksets still work after making all the changes for compound linksets. +Use PostTaint callback to do rebuilds for constraint linksets to reduce rebuilding Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. For compound linksets, add ability to remove or reposition individual child shapes. -Disable activity of passive linkset children. - Since the linkset is a compound object, the old prims are left lying - around and need to be phantomized so they don't collide, ... Speed up creation of large physical linksets For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. REALLY bad for very large physical linksets (freezes the sim for many seconds). @@ -138,25 +136,21 @@ MORE Use the HACD convex hull routine in Bullet rather than the C# version. Do we need to do convex hulls all the time? Can complex meshes be left meshes? There is some problem with meshes and collisions -Test avatar walking up stairs. How does compare with SL. - Radius of the capsule affects ability to climb edges. + Hulls are not as detailed as meshes. Hulled vehicles insides are different shape. Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. Use a different capsule shape for avatar when sitting LL uses a pyrimidal shape scaled by the avatar's bounding box http://wiki.secondlife.com/wiki/File:Avmeshforms.png - Performance test with lots of avatars. Can BulletSim support a thousand? Optimize collisions in C++: only send up to the object subscribed to collisions. Use collision subscription and remove the collsion(A,B) and collision(B,A) Check whether SimMotionState needs large if statement (see TODO). - Implement 'top colliders' info. Avatar jump Performance measurement and changes to make quicker. Implement detailed physics stats (GetStats()). - Measure performance improvement from hulls Test not using ghost objects for volume detect implementation. Performance of closures and delegates for taint processing @@ -164,9 +158,7 @@ Performance of closures and delegates for taint processing Is any slowdown introduced by the existing implementation significant? Is there are more efficient method of implementing pre and post step actions? See http://www.codeproject.com/Articles/29922/Weak-Events-in-C - Physics Arena central pyramid: why is one side permiable? - In SL, perfect spheres don't seem to have rolling friction. Add special case. Enforce physical parameter min/max: Gravity: [-1, 28] @@ -197,22 +189,19 @@ Generalize Dynamics and PID with standardized motors. Generalize Linkset and vehicles into PropertyManagers Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies Potentially add events for shape destruction, etc. -Complete implemention of preStepActions - Replace vehicle step call with prestep event. - Is there a need for postStepActions? postStepTaints? +Better mechanism for resetting linkset set and vehicle parameters when body rebuilt. + BSPrim.CreateGeomAndObject is kludgy with the callbacks, etc. Implement linkset by setting position of children when root updated. (LinksetManual) Linkset implementation using manual prim movement. LinkablePrim class? Would that simplify/centralize the linkset logic? BSScene.UpdateParameterSet() is broken. How to set params on objects? -Remove HeightmapInfo from terrain specification - Since C++ code does not need terrain height, this structure et al are not needed. Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will - bob at the water level. BSPrim.PositionSanityCheck(). + bob at the water level. BSPrim.PositionSanityCheck() Should taints check for existance or activeness of target? When destroying linksets/etc, taints can be generated for objects that are actually gone when the taint happens. Crashes don't happen because the taint closure keeps the object from being freed, but that is just an accident. - Possibly have and 'active' flag that is checked by the taint processor? + Possibly have an 'active' flag that is checked by the taint processor? Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? There are TOO MANY interfaces from BulletSim core to Bullet itself @@ -282,3 +271,18 @@ Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) Meshes rendering as bounding boxes (DONE) (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box) llMoveToTarget (Resolution: added simple motor to update the position.) +Angular motor direction is global coordinates rather than local coordinates (DONE) +Add vehicle collisions so IsColliding is properly reported. (DONE) + Needed for banking, limitMotorUp, movementLimiting, ... + (Resolution: added CollisionFlags.BS_VEHICLE_COLLISION and code to use it) +VehicleAddForce is not scaled by the simulation step but it is only + applied for one step. Should it be scaled? (DONE) + (Resolution: use force for timed things, Impulse for immediate, non-timed things) +Complete implemention of preStepActions (DONE) + Replace vehicle step call with prestep event. + Is there a need for postStepActions? postStepTaints? +Disable activity of passive linkset children. (DONE) + Since the linkset is a compound object, the old prims are left lying + around and need to be phantomized so they don't collide, ... +Remove HeightmapInfo from terrain specification (DONE) + Since C++ code does not need terrain height, this structure et al are not needed. \ No newline at end of file -- cgit v1.1 From 7e58bbaac6c5ebb5bf0d6a7a875a8316ac264128 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 16:27:06 -0800 Subject: BulletSim: Redo linear function coding so they can better interact. New algorithm for limitMotorUp that relies on going up when not colliding rather than distance from ground. Add parameter for turning on and off embedded source vehicle debugging. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 147 ++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 + 2 files changed, 91 insertions(+), 62 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 47f2759..2e44ab6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -134,6 +134,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene = myScene; Prim = myPrim; Type = Vehicle.TYPE_NONE; + SetupVehicleDebugging(); + } + + // Stopgap debugging enablement. Allows source level debugging but still checking + // in changes by making enablement of debugging flags from INI file. + public void SetupVehicleDebugging() + { + enableAngularVerticalAttraction = true; + enableAngularDeflection = true; + enableAngularBanking = true; + if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) + { + enableAngularVerticalAttraction = false; + enableAngularDeflection = false; + enableAngularBanking = false; + VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode"); + } } // Return 'true' if this vehicle is doing vehicle things @@ -576,8 +593,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Vehicles report collision events so we know when it's on the ground PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); - Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); - PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); + Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); + PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia); PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); // Set the gravity for the vehicle depending on the buoyancy @@ -586,7 +603,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", - Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping, grav); + Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, grav); } else { @@ -863,69 +880,47 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The movement computed in the linear motor is relative to the vehicle // coordinates. Rotate the movement to world coordinates. linearMotorContribution *= VehicleOrientation; - // All the contributions after this are world relative (mostly Z modifications) - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); + VehicleVelocity = linearMotorContribution; - Vector3 hoverContribution = ComputeLinearHover(pTimestep); + ComputeLinearTerrainHeightCorrection(pTimestep); - ComputeLinearBlockingEndPoint(pTimestep); - - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); + ComputeLinearHover(pTimestep); - // ================================================================== - // Select between velocities and forces. Forces will happen over time and - // will take into account inertia, collisions, etc. Velocities are - // raw updates to the velocity of the vehicle. - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution - + hoverContribution - + limitMotorUpContribution; + ComputeLinearBlockingEndPoint(pTimestep); - Vector3 newForce = Vector3.Zero; + ComputeLinearMotorUp(pTimestep); // If not changing some axis, reduce out velocity - if ((m_flags & (VehicleFlag.NO_X)) != 0) - newVelocity.X = 0; - if ((m_flags & (VehicleFlag.NO_Y)) != 0) - newVelocity.Y = 0; - if ((m_flags & (VehicleFlag.NO_Z)) != 0) - newVelocity.Z = 0; + if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) + { + Vector3 vel = VehicleVelocity; + if ((m_flags & (VehicleFlag.NO_X)) != 0) + vel.X = 0; + if ((m_flags & (VehicleFlag.NO_Y)) != 0) + vel.Y = 0; + if ((m_flags & (VehicleFlag.NO_Z)) != 0) + vel.Z = 0; + VehicleVelocity = vel; + } // ================================================================== // Clamp high or low velocities - float newVelocityLengthSq = newVelocity.LengthSquared(); + float newVelocityLengthSq = VehicleVelocity.LengthSquared(); if (newVelocityLengthSq > 1000f) { - newVelocity /= newVelocity.Length(); - newVelocity *= 1000f; + VehicleVelocity /= VehicleVelocity.Length(); + VehicleVelocity *= 1000f; } else if (newVelocityLengthSq < 0.001f) - newVelocity = Vector3.Zero; - - // ================================================================== - // Stuff new linear velocity into the vehicle. - // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. - // Also not scaled by mass since this is a super-physical setting of velocity. - VehicleVelocity = newVelocity; - - // Other linear forces are applied as forces. - Vector3 totalDownForce = newForce * m_vehicleMass; - if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) - { - VehicleAddForce(totalDownForce); - } + VehicleVelocity = Vector3.Zero; - VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},totDown={5},isColl={6},newVel={7}", - Prim.LocalID, - linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution, - totalDownForce, Prim.IsColliding, newVelocity ); + VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity ); } // end MoveLinear() - public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) + public void ComputeLinearTerrainHeightCorrection(float pTimestep) { - Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. // TODO: Consider taking the rotated size of the object or possibly casting a ray. if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) @@ -937,13 +932,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); } - return ret; } - public Vector3 ComputeLinearHover(float pTimestep) + public void ComputeLinearHover(float pTimestep) { - Vector3 ret = Vector3.Zero; - // m_VhoverEfficiency: 0=bouncy, 1=totally damped // m_VhoverTimescale: time to achieve height if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) @@ -976,6 +968,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 pos = VehiclePosition; pos.Z = m_VhoverTargetHeight; VehiclePosition = pos; + + VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos); } } else @@ -985,14 +979,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); + VehicleVelocity += new Vector3(0f, 0f, verticalCorrectionVelocity); + + VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", + Prim.LocalID, VehiclePosition, m_VhoverEfficiency, + m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, + verticalError, verticalCorrectionVelocity); } - VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}", - Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret); } - - return ret; } public bool ComputeLinearBlockingEndPoint(float pTimestep) @@ -1047,30 +1042,58 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: this code is wrong. Also, what should it do for boats (height from water)? // This is just using the ground and a general collision check. Should really be using // a downward raycast to find what is below. - public Vector3 ComputeLinearMotorUp(float pTimestep) + public void ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; - float distanceAboveGround = 0f; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { + // This code tries to decide if the object is not on the ground and then pushing down + /* float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); distanceAboveGround = VehiclePosition.Z - targetHeight; // Not colliding if the vehicle is off the ground if (!Prim.IsColliding) { // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - ret = new Vector3(0, 0, -distanceAboveGround); + VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); } // TODO: this calculation is wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. // TODO: add interaction with banking. - } - VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); - return ret; + */ + + // Another approach is to measure if we're going up. If going up and not colliding, + // the vehicle is in the air. Fix that by pushing down. + if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) + { + // Get rid of any of the velocity vector that is pushing us up. + VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z); + + // If we're pointed up into the air, we should nose down + Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; + // The rotation around the Y axis is pitch up or down + if (pointingDirection.Y > 0.01f) + { + float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y); + Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f); + // Rotate into world coordinates and apply to vehicle + angularCorrectionVector *= VehicleOrientation; + VehicleAddAngularForce(angularCorrectionVector); + VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}", + Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector); + } + else + { + VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}", + Prim.LocalID, VehicleVelocity, pointingDirection); + } + } + } } // ======================================================================= diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 23d573f..27ff047 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -80,6 +80,7 @@ public static class BSParam public static float AvatarStepForceFactor { get; private set; } public static float VehicleAngularDamping { get; private set; } + public static float VehicleDebuggingEnabled { get; private set; } public static float LinksetImplementation { get; private set; } public static float LinkConstraintUseFrameOffset { get; private set; } @@ -427,6 +428,11 @@ public static class BSParam (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return VehicleAngularDamping; }, (s,p,l,v) => { VehicleAngularDamping = v; } ), + new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return VehicleDebuggingEnabled; }, + (s,p,l,v) => { VehicleDebuggingEnabled = v; } ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, -- cgit v1.1 From daacd4deed9630b67738b342078f0b334e74aa4b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 17:40:22 -0800 Subject: Fix exception reporting in SceneObjectPart so it logs what the exception is rather than just saying it happened. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 232861e..44e8fdf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4050,9 +4050,9 @@ namespace OpenSim.Region.Framework.Scenes rigidBody, m_localId); } - catch + catch (Exception e) { - m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); + m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); pa = null; } -- cgit v1.1 From 93adc4cb6689b156db4db315d44b5ba0ddcd65ac Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 22:45:01 -0800 Subject: BulletSim: Add IsSelected attribute to physical objects. Have vehicles check to see if physical before trying to step. Replace vehicle gravity application. Previously relying on Bullet to apply gravity but since vehicles over-ride the velocity calculation, gravity never had a chance to accelerate the body down. Added AddForceImpulse as well as AddForce for those who need to apply immediate velocity updates. Use the impulse to apply the linear motion. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 + OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 126 ++++++++++++++++----- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 1 + OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 81 +++++++++---- 4 files changed, 162 insertions(+), 50 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 939d38a..aadb583 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -328,6 +328,10 @@ public sealed class BSCharacter : BSPhysObject public override bool Selected { set { _selected = value; } } + public override bool IsSelected + { + get { return _selected; } + } public override void CrossingFailure() { return; } public override void link(PhysicsActor obj) { return; } public override void delink() { return; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 2e44ab6..80fdfb9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. - // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) - // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. - // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + private float m_VehicleBuoyancy = 0f; + private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set //Attractor properties private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); @@ -149,14 +148,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin enableAngularVerticalAttraction = false; enableAngularDeflection = false; enableAngularBanking = false; - VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode"); + VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode", Prim.LocalID); } } // Return 'true' if this vehicle is doing vehicle things public bool IsActive { - get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } + get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); } } #region Vehicle parameter setting @@ -190,6 +189,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.BUOYANCY: m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); + m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); break; case Vehicle.HOVER_EFFICIENCY: m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); @@ -562,12 +562,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin 1f); m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + /* Not implemented m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, BSMotor.Infinite, BSMotor.InfiniteVector, m_verticalAttractionEfficiency); // Z goes away and we keep X and Y m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + */ } #endregion // Vehicle parameter setting @@ -599,11 +601,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Set the gravity for the vehicle depending on the buoyancy // TODO: what should be done if prim and vehicle buoyancy differ? - Vector3 grav = Prim.ComputeGravity(m_VehicleBuoyancy); - PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); + m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); + // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. + PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", - Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, grav); + Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); } else { @@ -643,6 +646,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3 m_knownPosition; private Vector3 m_knownVelocity; private Vector3 m_knownForce; + private Vector3 m_knownForceImpulse; private Quaternion m_knownOrientation; private Vector3 m_knownRotationalVelocity; private Vector3 m_knownRotationalForce; @@ -651,12 +655,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; private const int m_knownChangedForce = 1 << 2; - private const int m_knownChangedOrientation = 1 << 3; - private const int m_knownChangedRotationalVelocity = 1 << 4; - private const int m_knownChangedRotationalForce = 1 << 5; - private const int m_knownChangedTerrainHeight = 1 << 6; - private const int m_knownChangedWaterLevel = 1 << 7; - private const int m_knownChangedForwardVelocity = 1 << 8; + private const int m_knownChangedForceImpulse = 1 << 3; + private const int m_knownChangedOrientation = 1 << 4; + private const int m_knownChangedRotationalVelocity = 1 << 5; + private const int m_knownChangedRotationalForce = 1 << 6; + private const int m_knownChangedTerrainHeight = 1 << 7; + private const int m_knownChangedWaterLevel = 1 << 8; + private const int m_knownChangedForwardVelocity = 1 << 9; private void ForgetKnownVehicleProperties() { @@ -677,21 +682,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedVelocity) != 0) { Prim.ForceVelocity = m_knownVelocity; - PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); + // Fake out Bullet by making it think the velocity is the same as last time. + // Bullet does a bunch of smoothing for changing parameters. + // Since the vehicle is demanding this setting, we override Bullet's smoothing + // by telling Bullet the value was the same last time. + PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); } if ((m_knownChanged & m_knownChangedForce) != 0) Prim.AddForce((Vector3)m_knownForce, false, true); + if ((m_knownChanged & m_knownChangedForceImpulse) != 0) + Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false, true); + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = m_knownRotationalVelocity; - // Fake out Bullet by making it think the velocity is the same as last time. PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); } if ((m_knownChanged & m_knownChangedRotationalForce) != 0) + { Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + } // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. @@ -781,15 +794,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - private void VehicleAddForce(Vector3 aForce) + private void VehicleAddForce(Vector3 pForce) { if ((m_knownHas & m_knownChangedForce) == 0) { m_knownForce = Vector3.Zero; + m_knownHas |= m_knownChangedForce; } - m_knownForce += aForce; + m_knownForce += pForce; m_knownChanged |= m_knownChangedForce; - m_knownHas |= m_knownChangedForce; + } + + private void VehicleAddForceImpulse(Vector3 pImpulse) + { + if ((m_knownHas & m_knownChangedForceImpulse) == 0) + { + m_knownForceImpulse = Vector3.Zero; + m_knownHas |= m_knownChangedForceImpulse; + } + m_knownForceImpulse += pImpulse; + m_knownChanged |= m_knownChangedForceImpulse; } private Vector3 VehicleRotationalVelocity @@ -868,20 +892,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (PhysicsScene.VehiclePhysicalLoggingEnabled) PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); - VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", - Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); + VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", + Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); } // Apply the effect of the linear motor and other linear motions (like hover and float). private void MoveLinear(float pTimestep) { - Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); - - // The movement computed in the linear motor is relative to the vehicle - // coordinates. Rotate the movement to world coordinates. - linearMotorContribution *= VehicleOrientation; - - VehicleVelocity = linearMotorContribution; + ComputeLinearVelocity(pTimestep); ComputeLinearTerrainHeightCorrection(pTimestep); @@ -891,6 +909,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin ComputeLinearMotorUp(pTimestep); + ApplyGravity(pTimestep); + // If not changing some axis, reduce out velocity if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) { @@ -919,6 +939,43 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // end MoveLinear() + public void ComputeLinearVelocity(float pTimestep) + { + Vector3 linearMotorStep = m_linearMotor.Step(pTimestep); + + // The movement computed in the linear motor is relative to the vehicle + // coordinates. Rotate the movement to world coordinates. + Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation; + + // If we're a ground vehicle, don't loose any Z action (like gravity acceleration). + float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z + if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) + { + if (!Prim.IsColliding) + { + // If a ground vehicle and not on the ground, I want gravity effect + mixFactor = 0.2f; + } + } + else + { + // I'm not a ground vehicle but don't totally loose the effect of the environment + mixFactor = 0.8f; + } + linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z; + + // What we want to contribute to the vehicle's existing velocity + Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity; + + // Act against the inertia of the vehicle + linearMotorForce *= m_vehicleMass; + + VehicleAddForceImpulse(linearMotorForce); + + VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", + Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); + } + public void ComputeLinearTerrainHeightCorrection(float pTimestep) { // If below the terrain, move us above the ground a little. @@ -979,7 +1036,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly - VehicleVelocity += new Vector3(0f, 0f, verticalCorrectionVelocity); + VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", Prim.LocalID, VehiclePosition, m_VhoverEfficiency, @@ -1096,6 +1153,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } + private void ApplyGravity(float pTimeStep) + { + Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; + VehicleAddForce(appliedGravity); + + VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", + Prim.LocalID, m_VehicleGravity, appliedGravity); + } + // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e8575f6..2c84293 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -135,6 +135,7 @@ public abstract class BSPhysObject : PhysicsActor public virtual OMV.Vector3 Scale { get; set; } public abstract bool IsSolid { get; } public abstract bool IsStatic { get; } + public abstract bool IsSelected { get; } // Materialness public MaterialAttributes.Material Material { get; private set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 50ba343..02d06b4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -204,6 +204,10 @@ public sealed class BSPrim : BSPhysObject } } } + public override bool IsSelected + { + get { return _isSelected; } + } public override void CrossingFailure() { return; } // link me to the specified parent @@ -1153,33 +1157,70 @@ public sealed class BSPrim : BSPhysObject // This added force will only last the next simulation tick. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not - if (!IsStatic && force.IsFinite()) + if (!IsStatic) { - float magnitude = force.Length(); - if (magnitude > BSParam.MaxAddForceMagnitude) + if (force.IsFinite()) { - // Force has a limit - force = force / magnitude * BSParam.MaxAddForceMagnitude; - } + float magnitude = force.Length(); + if (magnitude > BSParam.MaxAddForceMagnitude) + { + // Force has a limit + force = force / magnitude * BSParam.MaxAddForceMagnitude; + } - OMV.Vector3 addForce = force; - // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + OMV.Vector3 addForce = force; + // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() - { - // Bullet adds this central force to the total force for this tick - DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); - if (PhysBody.HasPhysicalBody) + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { - PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); - ActivateIfPhysical(false); - } - }); + // Bullet adds this central force to the total force for this tick + DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); + if (PhysBody.HasPhysicalBody) + { + PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); + ActivateIfPhysical(false); + } + }); + } + else + { + m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } } - else + } + + public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) { + // for an object, doesn't matter if force is a pushforce or not + if (!IsStatic) { - m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); - return; + if (impulse.IsFinite()) + { + float magnitude = impulse.Length(); + if (magnitude > BSParam.MaxAddForceMagnitude) + { + // Force has a limit + impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude; + } + + // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); + OMV.Vector3 addImpulse = impulse; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() + { + // Bullet adds this impulse immediately to the velocity + DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); + if (PhysBody.HasPhysicalBody) + { + PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse); + ActivateIfPhysical(false); + } + }); + } + else + { + m_log.WarnFormat("{0}: AddForceImpulse: Got a NaN impulse applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } } } -- cgit v1.1 From eacc2561d14dbe9cba6966e3b32bfd776e044f8a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 10 Jan 2013 17:03:19 -0800 Subject: BulletSim: add osGetPhysicsEngineType() LSL function and update the physics engines to return the name that is specified in the INI file ("physics = XXX") as the type of engine. This os function is a little different than the others in that it does not throw an exception of one is not privilaged to use it. It merely returns an empty string. --- .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs | 2 +- .../BasicPhysicsPlugin/BasicPhysicsScene.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 9 +++- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 11 +++- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 2 +- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 3 +- OpenSim/Region/Physics/POSPlugin/POSPlugin.cs | 2 +- OpenSim/Region/Physics/POSPlugin/POSScene.cs | 4 +- .../Shared/Api/Implementation/OSSL_Api.cs | 59 ++++++++++++++++++---- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 ++ 12 files changed, 82 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs index 7ab2a03..373c7e0 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin public PhysicsScene GetScene(string sceneIdentifier) { - return new BasicScene(sceneIdentifier); + return new BasicScene(GetName(), sceneIdentifier); } public string GetName() diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index f5826ed..c4b9117 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -49,8 +49,10 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin //protected internal string sceneIdentifier; - public BasicScene(string _sceneIdentifier) + public BasicScene(string engineType, string _sceneIdentifier) { + EngineType = engineType; + Name = EngineType + "/" + _sceneIdentifier; //sceneIdentifier = _sceneIdentifier; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs index 65be52a..9442854 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs @@ -59,7 +59,7 @@ public class BSPlugin : IPhysicsPlugin { if (_mScene == null) { - _mScene = new BSScene(sceneIdentifier); + _mScene = new BSScene(GetName(), sceneIdentifier); } return (_mScene); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 4a6cebd..a5bdc07 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -167,11 +167,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public bool VehiclePhysicalLoggingEnabled { get; private set; } #region Construction and Initialization - public BSScene(string identifier) + public BSScene(string engineType, string identifier) { m_initialized = false; - // we are passed the name of the region we're working for. + + // The name of the region we're working for is passed to us. Keep for identification. RegionName = identifier; + + // Set identifying variables in the PhysicsScene interface. + EngineType = engineType; + Name = EngineType + "/" + RegionName; } public override void Initialise(IMesher meshmerizer, IConfigSource config) diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 488900e..201007b 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -62,13 +62,20 @@ namespace OpenSim.Region.Physics.Manager // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// - /// Name of this scene. Useful in debug messages to distinguish one OdeScene instance from another. + /// A unique identifying string for this instance of the physics engine. + /// Useful in debug messages to distinguish one OdeScene instance from another. + /// Usually set to include the region name that the physics engine is acting for. /// public string Name { get; protected set; } + /// + /// A string identifying the family of this physics engine. Most common values returned + /// are "OpenDynamicsEngine" and "BulletSim" but others are possible. + /// + public string EngineType { get; protected set; } + // The only thing that should register for this event is the SceneGraph // Anything else could cause problems. - public event physicsCrash OnPhysicsCrash; public static PhysicsScene Null diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 478dd95..07663b3 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.Physics.OdePlugin // http://opensimulator.org/mantis/view.php?id=2750). d.InitODE(); - m_scene = new OdeScene(sceneIdentifier); + m_scene = new OdeScene(GetName(), sceneIdentifier); } return m_scene; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index d53bd90..02a0b15 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -526,11 +526,12 @@ namespace OpenSim.Region.Physics.OdePlugin /// These settings need to be tweaked 'exactly' right or weird stuff happens. /// /// Name of the scene. Useful in debug messages. - public OdeScene(string name) + public OdeScene(string engineType, string name) { m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name); Name = name; + EngineType = engineType; nearCallback = near; triCallback = TriCallback; diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs index e6b42e6..ed086dd 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.POSPlugin public PhysicsScene GetScene(string sceneIdentifier) { - return new POSScene(sceneIdentifier); + return new POSScene(GetName(), sceneIdentifier); } public string GetName() diff --git a/OpenSim/Region/Physics/POSPlugin/POSScene.cs b/OpenSim/Region/Physics/POSPlugin/POSScene.cs index 2f24a50..d30d482 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSScene.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSScene.cs @@ -43,8 +43,10 @@ namespace OpenSim.Region.Physics.POSPlugin //protected internal string sceneIdentifier; - public POSScene(String _sceneIdentifier) + public POSScene(string engineType, String _sceneIdentifier) { + EngineType = engineType; + Name = EngineType + "/" + _sceneIdentifier; //sceneIdentifier = _sceneIdentifier; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 33c02ef..958a448 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -245,11 +245,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); } + // Returns of the function is allowed. Throws a script exception if not allowed. public void CheckThreatLevel(ThreatLevel level, string function) { if (!m_OSFunctionsEnabled) OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws + string reasonWhyNot = CheckThreatLevelTest(level, function); + if (!String.IsNullOrEmpty(reasonWhyNot)) + { + OSSLError(reasonWhyNot); + } + } + + // Check to see if function is allowed. Returns an empty string if function permitted + // or a string explaining why this function can't be used. + private string CheckThreatLevelTest(ThreatLevel level, string function) + { if (!m_FunctionPerms.ContainsKey(function)) { FunctionPerms perms = new FunctionPerms(); @@ -329,10 +341,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // Allow / disallow by threat level if (level > m_MaxThreatLevel) - OSSLError( + return String.Format( "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.", - function, m_MaxThreatLevel, level)); + function, m_MaxThreatLevel, level); } else { @@ -342,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) { // prim owner is in the list of allowed owners - return; + return String.Empty; } UUID ownerID = m_item.OwnerID; @@ -354,7 +366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) { - return; + return String.Empty; } } @@ -365,7 +377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (land.LandData.OwnerID == ownerID) { - return; + return String.Empty; } } @@ -375,7 +387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Only Estate Managers may use the function if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) { - return; + return String.Empty; } } @@ -384,25 +396,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (World.RegionInfo.EstateSettings.EstateOwner == ownerID) { - return; + return String.Empty; } } if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) - OSSLError( + return( String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", function)); if (m_item.CreatorID != ownerID) { if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) - OSSLError( - String.Format("{0} permission denied. Script permissions error.", - function)); + return String.Format("{0} permission denied. Script permissions error.", function); } } } + return String.Empty; } internal void OSSLDeprecated(string function, string replacement) @@ -1558,6 +1569,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public string osGetPhysicsEngineType() + { + // High because it can be used to target attacks to known weaknesses + // This would allow a new class of griefer scripts that don't even + // require their user to know what they are doing (see script + // kiddie) + // Because it would be nice if scripts didn't blow up if the information + // about the physics engine, this function returns an empty string if + // the user does not have permission to see it. This as opposed to + // throwing an exception. + m_host.AddScriptLPS(1); + string ret = String.Empty; + if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType"))) + { + if (m_ScriptEngine.World.PhysicsScene != null) + { + ret = m_ScriptEngine.World.PhysicsScene.EngineType; + // An old physics engine might have an uninitialized engine type + if (ret == null) + ret = "unknown"; + } + } + + return ret; + } + public string osGetSimulatorVersion() { // High because it can be used to target attacks to known weaknesses diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index cdd9ea8..51d0581 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -259,6 +259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osGetScriptEngineName(); string osGetSimulatorVersion(); + string osGetPhysicsEngineType(); Object osParseJSONNew(string JSON); Hashtable osParseJSON(string JSON); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index afa9ae0..c9902e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -420,6 +420,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetScriptEngineName(); } + public string osGetPhysicsEngineType() + { + return m_OSSL_Functions.osGetPhysicsEngineType(); + } + public string osGetSimulatorVersion() { return m_OSSL_Functions.osGetSimulatorVersion(); -- cgit v1.1 From 459fcd81c9d6e7c92738b40f1b4b4fe746699379 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 11 Jan 2013 16:36:34 -0800 Subject: BulletSim: move center of gravity of linkset to its geometric center. Necessitated allowing simulator and physical position of a body to get out of sync since Bullet assumes that <0,0,0> is the center of mass. Update DLLs and SOs for the UpdateChildTransform so positions of individual prim in a linkset can be implemented. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 9 ++++ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 1 + .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 2 + OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 13 +++-- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 4 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 55 ++++++++++++++++----- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 10 ++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 40 +++++++++++---- .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 + bin/lib32/BulletSim.dll | Bin 551936 -> 551424 bytes bin/lib32/libBulletSim.so | Bin 1715168 -> 1720142 bytes bin/lib64/BulletSim.dll | Bin 700928 -> 700416 bytes bin/lib64/libBulletSim.so | Bin 1857493 -> 1858627 bytes 14 files changed, 106 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 14de2eb..0fef67c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -327,6 +327,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); } +public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) +{ + BulletShapeUnman shapeu = pShape as BulletShapeUnman; + BSAPICPP.UpdateChildTransform2(shapeu.ptr, childIndex, pos, rot, shouldRecalculateLocalAabb); +} + public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) { BulletShapeUnman shapeu = shape as BulletShapeUnman; @@ -1357,6 +1363,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateChildTransform2(IntPtr pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 0c7f315..b6ff52b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1212,6 +1212,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } + public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ } public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 794ee17..bc163eb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -342,6 +342,8 @@ public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape c public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); +public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); + public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 80fdfb9..bcebaec 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -148,7 +148,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin enableAngularVerticalAttraction = false; enableAngularDeflection = false; enableAngularBanking = false; - VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode", Prim.LocalID); } } @@ -690,10 +689,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin } if ((m_knownChanged & m_knownChangedForce) != 0) - Prim.AddForce((Vector3)m_knownForce, false, true); + Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); if ((m_knownChanged & m_knownChangedForceImpulse) != 0) - Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false, true); + Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { @@ -703,7 +702,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedRotationalForce) != 0) { - Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); } // If we set one of the values (ie, the physics engine didn't do it) we must force @@ -970,7 +969,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Act against the inertia of the vehicle linearMotorForce *= m_vehicleMass; - VehicleAddForceImpulse(linearMotorForce); + VehicleAddForceImpulse(linearMotorForce * pTimestep); VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); @@ -1033,7 +1032,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Error is positive if below the target and negative if above. float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; - float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; + float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep; // TODO: implement m_VhoverEfficiency correctly VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); @@ -1323,7 +1322,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // this creates an over-correction and then wabbling as the target is overshot. // TODO: rethink how the different correction computations inter-relate. - if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) + if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) { // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 756faed..cbd160f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -152,6 +152,7 @@ public abstract class BSLinkset if (IsRoot(child)) { // Cannot remove the root from a linkset. + child.PositionDisplacement = OMV.Vector3.Zero; return this; } RemoveChildFromLinkset(child); @@ -159,6 +160,7 @@ public abstract class BSLinkset } // The child is down to a linkset of just itself + child.PositionDisplacement = OMV.Vector3.Zero; return BSLinkset.Factory(PhysicsScene, child); } @@ -310,7 +312,7 @@ public abstract class BSLinkset foreach (BSPhysObject bp in m_children) { - com += bp.Position * bp.RawMass; + com += bp.Position; } com /= (m_children.Count + 1); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index bd03d31..ad8024c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin // removed from the linkset. sealed class BSLinksetCompoundInfo : BSLinksetInfo { - public OMV.Vector3 OffsetPos; + public int Index; + public OMV.Vector3 OffsetFromRoot; + public OMV.Vector3 OffsetFromCenterOfMass; public OMV.Quaternion OffsetRot; - public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) + public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r) { - OffsetPos = p; + Index = indx; + OffsetFromRoot = p; + OffsetFromCenterOfMass = p; OffsetRot = r; } public override void Clear() { - OffsetPos = OMV.Vector3.Zero; + Index = 0; + OffsetFromRoot = OMV.Vector3.Zero; + OffsetFromCenterOfMass = OMV.Vector3.Zero; OffsetRot = OMV.Quaternion.Identity; } public override string ToString() { StringBuilder buff = new StringBuilder(); - buff.Append(""); @@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset return ret; } + // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. + // Called at taint-time. public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) { // The user moving a child around requires the rebuilding of the linkset compound shape @@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset && !physicalUpdate && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) { + // TODO: replace this with are calculation of the child prim's orientation and pos. updated.LinksetInfo = null; ScheduleRebuild(updated); } @@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset if (inTaintTime) { OMV.Vector3 oldPos = child.RawPosition; - child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; + child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot; child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", child.LocalID, oldPos, lci, child.RawPosition); @@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset else { // TaintedObject is not used here so the raw position is set now and not at taint-time. - child.Position = LinksetRoot.RawPosition + lci.OffsetPos; + child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot; child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; } } @@ -316,10 +329,23 @@ public sealed class BSLinksetCompound : BSLinkset // Cause the root shape to be rebuilt as a compound object with just the root in it LinksetRoot.ForceBodyShapeRebuild(true); + // The center of mass for the linkset is the geometric center of the group. + // Compute a displacement for each component so it is relative to the center-of-mass. + OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter(); + OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; + + // Since we're displacing the center of the shape, we need to move the body in the world + LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation; + + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", + LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); // Add a shape for each of the other children in the linkset + int memberIndex = 1; ForEachMember(delegate(BSPhysObject cPrim) { if (!IsRoot(cPrim)) @@ -337,13 +363,14 @@ public sealed class BSLinksetCompound : BSLinkset OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); + lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot); + lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement; cPrim.LinksetInfo = lci; DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); } - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", - LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}", + LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci); if (cPrim.PhysShape.isNativeShape) { @@ -359,7 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); } else { @@ -371,8 +398,10 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); } - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); } + lci.Index = memberIndex; + memberIndex++; } return false; // 'false' says to move onto the next child in the list }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 2c84293..185f111 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -73,6 +73,8 @@ public abstract class BSPhysObject : PhysicsActor // A linkset of just me Linkset = BSLinkset.Factory(PhysicsScene, this); + PositionDisplacement = OMV.Vector3.Zero; + LastAssetBuildFailed = false; // Default material type @@ -157,6 +159,14 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } + // Position is what the simulator thinks the positions of the prim is. + // Because Bullet needs the zero coordinate to be the center of mass of the linkset, + // sometimes it is necessary to displace the position the physics engine thinks + // the position is. PositionDisplacement must be added and removed from the + // position as the simulator position is stored and fetched from the physics + // engine. + public virtual OMV.Vector3 PositionDisplacement { get; set; } + public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 02d06b4..003dc54 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject private bool _grabbed; private bool _isSelected; private bool _isVolumeDetect; + + // _position is what the simulator thinks the positions of the prim is. private OMV.Vector3 _position; + private float _mass; // the mass of this object private float _density; private OMV.Vector3 _force; @@ -320,18 +323,37 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 ForcePosition { get { - _position = PhysicsScene.PE.GetPosition(PhysBody); + _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; return _position; } set { _position = value; if (PhysBody.HasPhysicalBody) { - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); ActivateIfPhysical(false); } } } + // Override to have position displacement immediately update the physical position. + // A feeble attempt to keep the sim and physical positions in sync + // Must be called at taint time. + public override OMV.Vector3 PositionDisplacement + { + get + { + return base.PositionDisplacement; + } + set + { + base.PositionDisplacement = value; + PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate() + { + if (PhysBody.HasPhysicalBody) + PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation); + }); + } + } // Check that the current position is sane and, if not, modify the position to make it so. // Check for being below terrain and being out of bounds. @@ -590,6 +612,7 @@ public sealed class BSPrim : BSPhysObject _velocity = value; if (PhysBody.HasPhysicalBody) { + DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); ActivateIfPhysical(false); } @@ -654,12 +677,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { - if (PhysBody.HasPhysicalBody) - { - // _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody); - // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); - } + ForceOrientation = _orientation; }); } } @@ -674,7 +692,8 @@ public sealed class BSPrim : BSPhysObject set { _orientation = value; - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + if (PhysBody.HasPhysicalBody) + PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); } } public override int PhysicsActorType { @@ -813,7 +832,7 @@ public sealed class BSPrim : BSPhysObject // PhysicsScene.PE.ClearAllForces(BSBody); // For good measure, make sure the transform is set through to the motion state - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); // Center of mass is at the center of the object // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); @@ -1615,6 +1634,7 @@ public sealed class BSPrim : BSPhysObject } // Assign directly to the local variables so the normal set actions do not happen + entprop.Position -= PositionDisplacement; _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index f0c6b99..addab29 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -906,7 +906,7 @@ public sealed class BSShapeCollection : IDisposable } } - // While we figure out the real problem, stick a simple native shape on the object. + // While we figure out the real problem, stick in a simple box for the object. BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 1540dbb..59cbab9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -170,6 +170,8 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179 INTERNAL IMPROVEMENT/CLEANUP ================================================= +Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to + BSScene.TaintedObject() could immediately execute the callback if already in taint time. Create the physical wrapper classes (BulletBody, BulletShape) by methods on BSAPITemplate and make their actual implementation Bullet engine specific. For the short term, just call the existing functions in ShapeCollection. diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 093ea31..014eca4 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 4d7018a..5e4d8cc 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 7956447..d00549e 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 2ce7f77..b94e264 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 8bf0a9f85dda4b1831630b65620d5c6868196c11 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 13 Jan 2013 22:32:31 -0800 Subject: BulletSim: disable center-of-mass computation for linksets until debugged. Move physical prim above ground if it is underground. Previously tried to correct by applying and up force but the prim would never go through the ground. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 35 +++++++++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 26 ++++++++-------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index ad8024c..5a1b5c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -319,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! + private bool disableCOM = true; // disable until we get this debugged private void RecomputeLinksetCompound() { try @@ -331,15 +332,26 @@ public sealed class BSLinksetCompound : BSLinkset // The center of mass for the linkset is the geometric center of the group. // Compute a displacement for each component so it is relative to the center-of-mass. - OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter(); - OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; + // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass + OMV.Vector3 centerOfMass; + OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; + if (disableCOM) // DEBUG DEBUG + { // DEBUG DEBUG + centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG + LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; + } // DEBUG DEBUG + else + { + centerOfMass = ComputeLinksetGeometricCenter(); + centerDisplacement = centerOfMass - LinksetRoot.RawPosition; - // Since we're displacing the center of the shape, we need to move the body in the world - LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation; + // Since we're displacing the center of the shape, we need to move the body in the world + LinksetRoot.PositionDisplacement = centerDisplacement; - PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", - LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", + LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + } DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); @@ -357,14 +369,15 @@ public sealed class BSLinksetCompound : BSLinkset BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; if (lci == null) { - // Each child position and rotation is given relative to the root. + // Each child position and rotation is given relative to the center-of-mass. OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); - OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot); - lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement; + lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); + lci.OffsetFromRoot = displacementFromRoot; cPrim.LinksetInfo = lci; DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 003dc54..e5f7ab7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -297,7 +297,7 @@ public sealed class BSPrim : BSPhysObject */ // don't do the GetObjectPosition for root elements because this function is called a zillion times. - // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); + // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; return _position; } set { @@ -362,7 +362,7 @@ public sealed class BSPrim : BSPhysObject { bool ret = false; - if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) { // The physical object is out of the known/simulated area. // Upper levels of code will handle the transition to other areas so, for @@ -376,8 +376,11 @@ public sealed class BSPrim : BSPhysObject { DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); float targetHeight = terrainHeight + (Size.Z / 2f); - // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. - upForce.Z = (terrainHeight - RawPosition.Z) * 1f; + // If the object is below ground it just has to be moved up because pushing will + // not get it through the terrain + _position.Z = targetHeight; + if (!inTaintTime) + ForcePosition = _position; ret = true; } @@ -389,20 +392,15 @@ public sealed class BSPrim : BSPhysObject { // Upforce proportional to the distance away from the water. Correct the error in 1 sec. upForce.Z = (waterHeight - RawPosition.Z) * 1f; + + // Apply upforce and overcome gravity. + OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; + DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); + AddForce(correctionForce, false, inTaintTime); ret = true; } } - // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. - // TODO: This should be intergrated with a geneal physics action mechanism. - // TODO: This should be moderated with PID'ness. - if (ret) - { - // Apply upforce and overcome gravity. - OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; - DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); - AddForce(correctionForce, false, inTaintTime); - } return ret; } -- cgit v1.1