aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-01-15 00:24:51 +0000
committerJustin Clark-Casey (justincc)2013-01-15 00:24:51 +0000
commitc846cefda97bd59b7707147d7ae1a520c9121127 (patch)
treeee23e4b451087874a8149348e010a905817121f7 /OpenSim
parentrefactor: Simplify ScriptInstance by retaining reference to SceneObjectPart i... (diff)
parentBulletSim: fix not moving physical objects below terrain to over terrain. (diff)
downloadopensim-SC_OLD-c846cefda97bd59b7707147d7ae1a520c9121127.zip
opensim-SC_OLD-c846cefda97bd59b7707147d7ae1a520c9121127.tar.gz
opensim-SC_OLD-c846cefda97bd59b7707147d7ae1a520c9121127.tar.bz2
opensim-SC_OLD-c846cefda97bd59b7707147d7ae1a520c9121127.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs4
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs2
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs11
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs1
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs8
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs282
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs72
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs40
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs172
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs27
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt60
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs11
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs3
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSPlugin.cs2
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSScene.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs59
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs5
26 files changed, 554 insertions, 246 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 504df40..a8517e6 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -6428,8 +6428,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6428 6428
6429 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; 6429 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit;
6430 if (handlerAgentRequestSit != null) 6430 if (handlerAgentRequestSit != null)
6431 handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, 6431 if (!(agentRequestSit.AgentData == null
6432 agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); 6432 || agentRequestSit.TargetObject == null
6433 || agentRequestSit.TargetObject.TargetID == null
6434 || agentRequestSit.TargetObject.Offset == null))
6435 {
6436 var sp = m_scene.GetScenePresence(agentRequestSit.AgentData.AgentID);
6437 if (sp == null || sp.ParentID != 0) // ignore packet if agent is already sitting
6438 return true;
6439
6440 handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID,
6441 agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
6442 }
6433 } 6443 }
6434 return true; 6444 return true;
6435 } 6445 }
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
4050 rigidBody, 4050 rigidBody,
4051 m_localId); 4051 m_localId);
4052 } 4052 }
4053 catch 4053 catch (Exception e)
4054 { 4054 {
4055 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); 4055 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4056 pa = null; 4056 pa = null;
4057 } 4057 }
4058 4058
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
49 49
50 public PhysicsScene GetScene(string sceneIdentifier) 50 public PhysicsScene GetScene(string sceneIdentifier)
51 { 51 {
52 return new BasicScene(sceneIdentifier); 52 return new BasicScene(GetName(), sceneIdentifier);
53 } 53 }
54 54
55 public string GetName() 55 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
49 49
50 //protected internal string sceneIdentifier; 50 //protected internal string sceneIdentifier;
51 51
52 public BasicScene(string _sceneIdentifier) 52 public BasicScene(string engineType, string _sceneIdentifier)
53 { 53 {
54 EngineType = engineType;
55 Name = EngineType + "/" + _sceneIdentifier;
54 //sceneIdentifier = _sceneIdentifier; 56 //sceneIdentifier = _sceneIdentifier;
55 } 57 }
56 58
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
index 14de2eb..9ff7084 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
@@ -202,7 +202,7 @@ private void BulletLoggerPhysLog(string msg)
202} 202}
203 203
204public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, 204public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
205 out int updatedEntityCount, out int collidersCount) 205 out int updatedEntityCount, out int collidersCount)
206{ 206{
207 BulletWorldUnman worldu = world as BulletWorldUnman; 207 BulletWorldUnman worldu = world as BulletWorldUnman;
208 return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); 208 return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount);
@@ -327,6 +327,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet
327 BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); 327 BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr);
328} 328}
329 329
330public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb)
331{
332 BulletShapeUnman shapeu = pShape as BulletShapeUnman;
333 BSAPICPP.UpdateChildTransform2(shapeu.ptr, childIndex, pos, rot, shouldRecalculateLocalAabb);
334}
335
330public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) 336public override void RecalculateCompoundShapeLocalAabb(BulletShape shape)
331{ 337{
332 BulletShapeUnman shapeu = shape as BulletShapeUnman; 338 BulletShapeUnman shapeu = shape as BulletShapeUnman;
@@ -1357,6 +1363,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap
1357public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); 1363public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
1358 1364
1359[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1365[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1366public static extern void UpdateChildTransform2(IntPtr pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
1367
1368[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1360public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); 1369public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape);
1361 1370
1362[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1371[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
1212 1212
1213 public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } 1213 public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; }
1214 public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } 1214 public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ }
1215 public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ }
1215 1216
1216 public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin) 1217 public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin)
1217 { 1218 {
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
342 342
343public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); 343public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
344 344
345public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
346
345public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); 347public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
346 348
347public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); 349public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 939d38a..a5fec87 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -126,9 +126,9 @@ public sealed class BSCharacter : BSPhysObject
126 DetailLog("{0},BSCharacter.Destroy", LocalID); 126 DetailLog("{0},BSCharacter.Destroy", LocalID);
127 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() 127 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
128 { 128 {
129 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 129 PhysicsScene.Shapes.DereferenceBody(PhysBody, true /* inTaintTime */, null /* bodyCallback */);
130 PhysBody.Clear(); 130 PhysBody.Clear();
131 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 131 PhysicsScene.Shapes.DereferenceShape(PhysShape, true /* inTaintTime */, null /* bodyCallback */);
132 PhysShape.Clear(); 132 PhysShape.Clear();
133 }); 133 });
134 } 134 }
@@ -328,6 +328,10 @@ public sealed class BSCharacter : BSPhysObject
328 public override bool Selected { 328 public override bool Selected {
329 set { _selected = value; } 329 set { _selected = value; }
330 } 330 }
331 public override bool IsSelected
332 {
333 get { return _selected; }
334 }
331 public override void CrossingFailure() { return; } 335 public override void CrossingFailure() { return; }
332 public override void link(PhysicsActor obj) { return; } 336 public override void link(PhysicsActor obj) { return; }
333 public override void delink() { return; } 337 public override void delink() { return; }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index c34c05a..bcebaec 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
108 private float m_VhoverEfficiency = 0f; 108 private float m_VhoverEfficiency = 0f;
109 private float m_VhoverTimescale = 0f; 109 private float m_VhoverTimescale = 0f;
110 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 110 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
111 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 111 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
112 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) 112 private float m_VehicleBuoyancy = 0f;
113 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. 113 private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set
114 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
115 114
116 //Attractor properties 115 //Attractor properties
117 private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); 116 private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
@@ -124,17 +123,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 static readonly float PIOverFour = ((float)Math.PI) / 4f; 123 static readonly float PIOverFour = ((float)Math.PI) / 4f;
125 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 124 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
126 125
126 // For debugging, flags to turn on and off individual corrections.
127 private bool enableAngularVerticalAttraction = true;
128 private bool enableAngularDeflection = true;
129 private bool enableAngularBanking = true;
130
127 public BSDynamics(BSScene myScene, BSPrim myPrim) 131 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 132 {
129 PhysicsScene = myScene; 133 PhysicsScene = myScene;
130 Prim = myPrim; 134 Prim = myPrim;
131 Type = Vehicle.TYPE_NONE; 135 Type = Vehicle.TYPE_NONE;
136 SetupVehicleDebugging();
137 }
138
139 // Stopgap debugging enablement. Allows source level debugging but still checking
140 // in changes by making enablement of debugging flags from INI file.
141 public void SetupVehicleDebugging()
142 {
143 enableAngularVerticalAttraction = true;
144 enableAngularDeflection = true;
145 enableAngularBanking = true;
146 if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse)
147 {
148 enableAngularVerticalAttraction = false;
149 enableAngularDeflection = false;
150 enableAngularBanking = false;
151 }
132 } 152 }
133 153
134 // Return 'true' if this vehicle is doing vehicle things 154 // Return 'true' if this vehicle is doing vehicle things
135 public bool IsActive 155 public bool IsActive
136 { 156 {
137 get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } 157 get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); }
138 } 158 }
139 159
140 #region Vehicle parameter setting 160 #region Vehicle parameter setting
@@ -168,6 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
168 break; 188 break;
169 case Vehicle.BUOYANCY: 189 case Vehicle.BUOYANCY:
170 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); 190 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
191 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
171 break; 192 break;
172 case Vehicle.HOVER_EFFICIENCY: 193 case Vehicle.HOVER_EFFICIENCY:
173 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); 194 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
@@ -540,12 +561,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
540 1f); 561 1f);
541 m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 562 m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
542 563
564 /* Not implemented
543 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, 565 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
544 BSMotor.Infinite, BSMotor.InfiniteVector, 566 BSMotor.Infinite, BSMotor.InfiniteVector,
545 m_verticalAttractionEfficiency); 567 m_verticalAttractionEfficiency);
546 // Z goes away and we keep X and Y 568 // Z goes away and we keep X and Y
547 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); 569 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
548 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 570 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
571 */
549 } 572 }
550 #endregion // Vehicle parameter setting 573 #endregion // Vehicle parameter setting
551 574
@@ -571,15 +594,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
571 // Vehicles report collision events so we know when it's on the ground 594 // Vehicles report collision events so we know when it's on the ground
572 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 595 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
573 596
574 Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); 597 Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
575 PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); 598 PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia);
576 PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); 599 PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
577 600
578 Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); 601 // Set the gravity for the vehicle depending on the buoyancy
579 PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); 602 // TODO: what should be done if prim and vehicle buoyancy differ?
603 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
604 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
605 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
580 606
581 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", 607 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}",
582 Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); 608 Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity);
583 } 609 }
584 else 610 else
585 { 611 {
@@ -619,6 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
619 private Vector3 m_knownPosition; 645 private Vector3 m_knownPosition;
620 private Vector3 m_knownVelocity; 646 private Vector3 m_knownVelocity;
621 private Vector3 m_knownForce; 647 private Vector3 m_knownForce;
648 private Vector3 m_knownForceImpulse;
622 private Quaternion m_knownOrientation; 649 private Quaternion m_knownOrientation;
623 private Vector3 m_knownRotationalVelocity; 650 private Vector3 m_knownRotationalVelocity;
624 private Vector3 m_knownRotationalForce; 651 private Vector3 m_knownRotationalForce;
@@ -627,12 +654,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
627 private const int m_knownChangedPosition = 1 << 0; 654 private const int m_knownChangedPosition = 1 << 0;
628 private const int m_knownChangedVelocity = 1 << 1; 655 private const int m_knownChangedVelocity = 1 << 1;
629 private const int m_knownChangedForce = 1 << 2; 656 private const int m_knownChangedForce = 1 << 2;
630 private const int m_knownChangedOrientation = 1 << 3; 657 private const int m_knownChangedForceImpulse = 1 << 3;
631 private const int m_knownChangedRotationalVelocity = 1 << 4; 658 private const int m_knownChangedOrientation = 1 << 4;
632 private const int m_knownChangedRotationalForce = 1 << 5; 659 private const int m_knownChangedRotationalVelocity = 1 << 5;
633 private const int m_knownChangedTerrainHeight = 1 << 6; 660 private const int m_knownChangedRotationalForce = 1 << 6;
634 private const int m_knownChangedWaterLevel = 1 << 7; 661 private const int m_knownChangedTerrainHeight = 1 << 7;
635 private const int m_knownChangedForwardVelocity = 1 << 8; 662 private const int m_knownChangedWaterLevel = 1 << 8;
663 private const int m_knownChangedForwardVelocity = 1 << 9;
636 664
637 private void ForgetKnownVehicleProperties() 665 private void ForgetKnownVehicleProperties()
638 { 666 {
@@ -653,21 +681,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
653 if ((m_knownChanged & m_knownChangedVelocity) != 0) 681 if ((m_knownChanged & m_knownChangedVelocity) != 0)
654 { 682 {
655 Prim.ForceVelocity = m_knownVelocity; 683 Prim.ForceVelocity = m_knownVelocity;
656 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); 684 // Fake out Bullet by making it think the velocity is the same as last time.
685 // Bullet does a bunch of smoothing for changing parameters.
686 // Since the vehicle is demanding this setting, we override Bullet's smoothing
687 // by telling Bullet the value was the same last time.
688 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity);
657 } 689 }
658 690
659 if ((m_knownChanged & m_knownChangedForce) != 0) 691 if ((m_knownChanged & m_knownChangedForce) != 0)
660 Prim.AddForce((Vector3)m_knownForce, false, true); 692 Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
693
694 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
695 Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
661 696
662 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) 697 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
663 { 698 {
664 Prim.ForceRotationalVelocity = m_knownRotationalVelocity; 699 Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
665 // Fake out Bullet by making it think the velocity is the same as last time.
666 PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); 700 PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
667 } 701 }
668 702
669 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 703 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
670 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); 704 {
705 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
706 }
671 707
672 // If we set one of the values (ie, the physics engine didn't do it) we must force 708 // If we set one of the values (ie, the physics engine didn't do it) we must force
673 // an UpdateProperties event to send the changes up to the simulator. 709 // an UpdateProperties event to send the changes up to the simulator.
@@ -757,15 +793,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
757 } 793 }
758 } 794 }
759 795
760 private void VehicleAddForce(Vector3 aForce) 796 private void VehicleAddForce(Vector3 pForce)
761 { 797 {
762 if ((m_knownHas & m_knownChangedForce) == 0) 798 if ((m_knownHas & m_knownChangedForce) == 0)
763 { 799 {
764 m_knownForce = Vector3.Zero; 800 m_knownForce = Vector3.Zero;
801 m_knownHas |= m_knownChangedForce;
765 } 802 }
766 m_knownForce += aForce; 803 m_knownForce += pForce;
767 m_knownChanged |= m_knownChangedForce; 804 m_knownChanged |= m_knownChangedForce;
768 m_knownHas |= m_knownChangedForce; 805 }
806
807 private void VehicleAddForceImpulse(Vector3 pImpulse)
808 {
809 if ((m_knownHas & m_knownChangedForceImpulse) == 0)
810 {
811 m_knownForceImpulse = Vector3.Zero;
812 m_knownHas |= m_knownChangedForceImpulse;
813 }
814 m_knownForceImpulse += pImpulse;
815 m_knownChanged |= m_knownChangedForceImpulse;
769 } 816 }
770 817
771 private Vector3 VehicleRotationalVelocity 818 private Vector3 VehicleRotationalVelocity
@@ -844,86 +891,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin
844 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 891 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
845 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 892 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
846 893
847 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 894 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
848 Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); 895 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
849 } 896 }
850 897
851 // Apply the effect of the linear motor and other linear motions (like hover and float). 898 // Apply the effect of the linear motor and other linear motions (like hover and float).
852 private void MoveLinear(float pTimestep) 899 private void MoveLinear(float pTimestep)
853 { 900 {
854 Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); 901 ComputeLinearVelocity(pTimestep);
855 902
856 // The movement computed in the linear motor is relative to the vehicle 903 ComputeLinearTerrainHeightCorrection(pTimestep);
857 // coordinates. Rotate the movement to world coordinates.
858 linearMotorContribution *= VehicleOrientation;
859 // All the contributions after this are world relative (mostly Z modifications)
860
861 // ==================================================================
862 // Buoyancy: force to overcome gravity.
863 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
864 // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity.
865 Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy;
866
867 Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep);
868 904
869 Vector3 hoverContribution = ComputeLinearHover(pTimestep); 905 ComputeLinearHover(pTimestep);
870 906
871 ComputeLinearBlockingEndPoint(pTimestep); 907 ComputeLinearBlockingEndPoint(pTimestep);
872 908
873 Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); 909 ComputeLinearMotorUp(pTimestep);
874 910
875 // ================================================================== 911 ApplyGravity(pTimestep);
876 Vector3 newVelocity = linearMotorContribution
877 + terrainHeightContribution
878 + hoverContribution
879 + limitMotorUpContribution;
880
881 Vector3 newForce = buoyancyContribution;
882 912
883 // If not changing some axis, reduce out velocity 913 // If not changing some axis, reduce out velocity
884 if ((m_flags & (VehicleFlag.NO_X)) != 0) 914 if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0)
885 newVelocity.X = 0; 915 {
886 if ((m_flags & (VehicleFlag.NO_Y)) != 0) 916 Vector3 vel = VehicleVelocity;
887 newVelocity.Y = 0; 917 if ((m_flags & (VehicleFlag.NO_X)) != 0)
888 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 918 vel.X = 0;
889 newVelocity.Z = 0; 919 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
920 vel.Y = 0;
921 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
922 vel.Z = 0;
923 VehicleVelocity = vel;
924 }
890 925
891 // ================================================================== 926 // ==================================================================
892 // Clamp high or low velocities 927 // Clamp high or low velocities
893 float newVelocityLengthSq = newVelocity.LengthSquared(); 928 float newVelocityLengthSq = VehicleVelocity.LengthSquared();
894 if (newVelocityLengthSq > 1000f) 929 if (newVelocityLengthSq > 1000f)
895 { 930 {
896 newVelocity /= newVelocity.Length(); 931 VehicleVelocity /= VehicleVelocity.Length();
897 newVelocity *= 1000f; 932 VehicleVelocity *= 1000f;
898 } 933 }
899 else if (newVelocityLengthSq < 0.001f) 934 else if (newVelocityLengthSq < 0.001f)
900 newVelocity = Vector3.Zero; 935 VehicleVelocity = Vector3.Zero;
901 936
902 // ================================================================== 937 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity );
903 // Stuff new linear velocity into the vehicle. 938
904 // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. 939 } // end MoveLinear()
905 VehicleVelocity = newVelocity; 940
941 public void ComputeLinearVelocity(float pTimestep)
942 {
943 Vector3 linearMotorStep = m_linearMotor.Step(pTimestep);
944
945 // The movement computed in the linear motor is relative to the vehicle
946 // coordinates. Rotate the movement to world coordinates.
947 Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation;
906 948
907 // Other linear forces are applied as forces. 949 // If we're a ground vehicle, don't loose any Z action (like gravity acceleration).
908 Vector3 totalDownForce = newForce * m_vehicleMass; 950 float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z
909 if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) 951 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
910 { 952 {
911 VehicleAddForce(totalDownForce); 953 if (!Prim.IsColliding)
954 {
955 // If a ground vehicle and not on the ground, I want gravity effect
956 mixFactor = 0.2f;
957 }
912 } 958 }
959 else
960 {
961 // I'm not a ground vehicle but don't totally loose the effect of the environment
962 mixFactor = 0.8f;
963 }
964 linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z;
913 965
914 VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", 966 // What we want to contribute to the vehicle's existing velocity
915 Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); 967 Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity;
916 VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}",
917 Prim.LocalID,
918 linearMotorContribution, terrainHeightContribution, hoverContribution,
919 limitMotorUpContribution, buoyancyContribution
920 );
921 968
922 } // end MoveLinear() 969 // Act against the inertia of the vehicle
970 linearMotorForce *= m_vehicleMass;
923 971
924 public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) 972 VehicleAddForceImpulse(linearMotorForce * pTimestep);
973
974 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}",
975 Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce);
976 }
977
978 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
925 { 979 {
926 Vector3 ret = Vector3.Zero;
927 // If below the terrain, move us above the ground a little. 980 // If below the terrain, move us above the ground a little.
928 // TODO: Consider taking the rotated size of the object or possibly casting a ray. 981 // TODO: Consider taking the rotated size of the object or possibly casting a ray.
929 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) 982 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
@@ -935,13 +988,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
935 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", 988 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
936 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); 989 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
937 } 990 }
938 return ret;
939 } 991 }
940 992
941 public Vector3 ComputeLinearHover(float pTimestep) 993 public void ComputeLinearHover(float pTimestep)
942 { 994 {
943 Vector3 ret = Vector3.Zero;
944
945 // m_VhoverEfficiency: 0=bouncy, 1=totally damped 995 // m_VhoverEfficiency: 0=bouncy, 1=totally damped
946 // m_VhoverTimescale: time to achieve height 996 // m_VhoverTimescale: time to achieve height
947 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 997 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
@@ -974,23 +1024,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
974 Vector3 pos = VehiclePosition; 1024 Vector3 pos = VehiclePosition;
975 pos.Z = m_VhoverTargetHeight; 1025 pos.Z = m_VhoverTargetHeight;
976 VehiclePosition = pos; 1026 VehiclePosition = pos;
1027
1028 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos);
977 } 1029 }
978 } 1030 }
979 else 1031 else
980 { 1032 {
981 // Error is positive if below the target and negative if above. 1033 // Error is positive if below the target and negative if above.
982 float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; 1034 float verticalError = m_VhoverTargetHeight - VehiclePosition.Z;
983 float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; 1035 float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep;
984 1036
985 // TODO: implement m_VhoverEfficiency correctly 1037 // TODO: implement m_VhoverEfficiency correctly
986 ret = new Vector3(0f, 0f, verticalCorrectionVelocity); 1038 VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity));
1039
1040 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}",
1041 Prim.LocalID, VehiclePosition, m_VhoverEfficiency,
1042 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
1043 verticalError, verticalCorrectionVelocity);
987 } 1044 }
988 1045
989 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}",
990 Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret);
991 } 1046 }
992
993 return ret;
994 } 1047 }
995 1048
996 public bool ComputeLinearBlockingEndPoint(float pTimestep) 1049 public bool ComputeLinearBlockingEndPoint(float pTimestep)
@@ -1045,30 +1098,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1045 // TODO: this code is wrong. Also, what should it do for boats (height from water)? 1098 // TODO: this code is wrong. Also, what should it do for boats (height from water)?
1046 // This is just using the ground and a general collision check. Should really be using 1099 // This is just using the ground and a general collision check. Should really be using
1047 // a downward raycast to find what is below. 1100 // a downward raycast to find what is below.
1048 public Vector3 ComputeLinearMotorUp(float pTimestep) 1101 public void ComputeLinearMotorUp(float pTimestep)
1049 { 1102 {
1050 Vector3 ret = Vector3.Zero; 1103 Vector3 ret = Vector3.Zero;
1051 float distanceAboveGround = 0f;
1052 1104
1053 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 1105 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
1054 { 1106 {
1107 // This code tries to decide if the object is not on the ground and then pushing down
1108 /*
1055 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); 1109 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
1056 distanceAboveGround = VehiclePosition.Z - targetHeight; 1110 distanceAboveGround = VehiclePosition.Z - targetHeight;
1057 // Not colliding if the vehicle is off the ground 1111 // Not colliding if the vehicle is off the ground
1058 if (!Prim.IsColliding) 1112 if (!Prim.IsColliding)
1059 { 1113 {
1060 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); 1114 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
1061 ret = new Vector3(0, 0, -distanceAboveGround); 1115 VehicleVelocity += new Vector3(0, 0, -distanceAboveGround);
1062 } 1116 }
1063 // TODO: this calculation is wrong. From the description at 1117 // TODO: this calculation is wrong. From the description at
1064 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce 1118 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
1065 // has a decay factor. This says this force should 1119 // has a decay factor. This says this force should
1066 // be computed with a motor. 1120 // be computed with a motor.
1067 // TODO: add interaction with banking. 1121 // TODO: add interaction with banking.
1068 } 1122 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
1069 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
1070 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); 1123 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
1071 return ret; 1124 */
1125
1126 // Another approach is to measure if we're going up. If going up and not colliding,
1127 // the vehicle is in the air. Fix that by pushing down.
1128 if (!Prim.IsColliding && VehicleVelocity.Z > 0.1)
1129 {
1130 // Get rid of any of the velocity vector that is pushing us up.
1131 VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z);
1132
1133 // If we're pointed up into the air, we should nose down
1134 Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
1135 // The rotation around the Y axis is pitch up or down
1136 if (pointingDirection.Y > 0.01f)
1137 {
1138 float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y);
1139 Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f);
1140 // Rotate into world coordinates and apply to vehicle
1141 angularCorrectionVector *= VehicleOrientation;
1142 VehicleAddAngularForce(angularCorrectionVector);
1143 VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}",
1144 Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector);
1145 }
1146 else
1147 {
1148 VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}",
1149 Prim.LocalID, VehicleVelocity, pointingDirection);
1150 }
1151 }
1152 }
1153 }
1154
1155 private void ApplyGravity(float pTimeStep)
1156 {
1157 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1158 VehicleAddForce(appliedGravity);
1159
1160 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}",
1161 Prim.LocalID, m_VehicleGravity, appliedGravity);
1072 } 1162 }
1073 1163
1074 // ======================================================================= 1164 // =======================================================================
@@ -1088,6 +1178,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1088 // for preventing ground vehicles with large linear deflection, like bumper cars, 1178 // for preventing ground vehicles with large linear deflection, like bumper cars,
1089 // from climbing their linear deflection into the sky. 1179 // from climbing their linear deflection into the sky.
1090 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement 1180 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
1181 // TODO: This is here because this is where ODE put it but documentation says it
1182 // is a linear effect. Where should this check go?
1091 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1183 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
1092 { 1184 {
1093 angularMotorContribution.X = 0f; 1185 angularMotorContribution.X = 0f;
@@ -1179,7 +1271,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1179 Vector3 ret = Vector3.Zero; 1271 Vector3 ret = Vector3.Zero;
1180 1272
1181 // If vertical attaction timescale is reasonable 1273 // If vertical attaction timescale is reasonable
1182 if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1274 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1183 { 1275 {
1184 // Take a vector pointing up and convert it from world to vehicle relative coords. 1276 // Take a vector pointing up and convert it from world to vehicle relative coords.
1185 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; 1277 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1230,7 +1322,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1230 // this creates an over-correction and then wabbling as the target is overshot. 1322 // this creates an over-correction and then wabbling as the target is overshot.
1231 // TODO: rethink how the different correction computations inter-relate. 1323 // TODO: rethink how the different correction computations inter-relate.
1232 1324
1233 if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) 1325 if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1234 { 1326 {
1235 // The direction the vehicle is moving 1327 // The direction the vehicle is moving
1236 Vector3 movingDirection = VehicleVelocity; 1328 Vector3 movingDirection = VehicleVelocity;
@@ -1303,7 +1395,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1303 { 1395 {
1304 Vector3 ret = Vector3.Zero; 1396 Vector3 ret = Vector3.Zero;
1305 1397
1306 if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1398 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1307 { 1399 {
1308 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. 1400 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
1309 // As the vehicle rolls to the right or left, the Y value will increase from 1401 // As the vehicle rolls to the right or left, the Y value will increase from
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
152 if (IsRoot(child)) 152 if (IsRoot(child))
153 { 153 {
154 // Cannot remove the root from a linkset. 154 // Cannot remove the root from a linkset.
155 child.PositionDisplacement = OMV.Vector3.Zero;
155 return this; 156 return this;
156 } 157 }
157 RemoveChildFromLinkset(child); 158 RemoveChildFromLinkset(child);
@@ -159,6 +160,7 @@ public abstract class BSLinkset
159 } 160 }
160 161
161 // The child is down to a linkset of just itself 162 // The child is down to a linkset of just itself
163 child.PositionDisplacement = OMV.Vector3.Zero;
162 return BSLinkset.Factory(PhysicsScene, child); 164 return BSLinkset.Factory(PhysicsScene, child);
163 } 165 }
164 166
@@ -310,7 +312,7 @@ public abstract class BSLinkset
310 312
311 foreach (BSPhysObject bp in m_children) 313 foreach (BSPhysObject bp in m_children)
312 { 314 {
313 com += bp.Position * bp.RawMass; 315 com += bp.Position;
314 } 316 }
315 com /= (m_children.Count + 1); 317 com /= (m_children.Count + 1);
316 } 318 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index bd03d31..5a1b5c7 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin
40// removed from the linkset. 40// removed from the linkset.
41sealed class BSLinksetCompoundInfo : BSLinksetInfo 41sealed class BSLinksetCompoundInfo : BSLinksetInfo
42{ 42{
43 public OMV.Vector3 OffsetPos; 43 public int Index;
44 public OMV.Vector3 OffsetFromRoot;
45 public OMV.Vector3 OffsetFromCenterOfMass;
44 public OMV.Quaternion OffsetRot; 46 public OMV.Quaternion OffsetRot;
45 public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) 47 public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
46 { 48 {
47 OffsetPos = p; 49 Index = indx;
50 OffsetFromRoot = p;
51 OffsetFromCenterOfMass = p;
48 OffsetRot = r; 52 OffsetRot = r;
49 } 53 }
50 public override void Clear() 54 public override void Clear()
51 { 55 {
52 OffsetPos = OMV.Vector3.Zero; 56 Index = 0;
57 OffsetFromRoot = OMV.Vector3.Zero;
58 OffsetFromCenterOfMass = OMV.Vector3.Zero;
53 OffsetRot = OMV.Quaternion.Identity; 59 OffsetRot = OMV.Quaternion.Identity;
54 } 60 }
55 public override string ToString() 61 public override string ToString()
56 { 62 {
57 StringBuilder buff = new StringBuilder(); 63 StringBuilder buff = new StringBuilder();
58 buff.Append("<p="); 64 buff.Append("<i=");
59 buff.Append(OffsetPos.ToString()); 65 buff.Append(Index.ToString());
66 buff.Append(",p=");
67 buff.Append(OffsetFromRoot.ToString());
68 buff.Append(",m=");
69 buff.Append(OffsetFromCenterOfMass.ToString());
60 buff.Append(",r="); 70 buff.Append(",r=");
61 buff.Append(OffsetRot.ToString()); 71 buff.Append(OffsetRot.ToString());
62 buff.Append(">"); 72 buff.Append(">");
@@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset
170 return ret; 180 return ret;
171 } 181 }
172 182
183 // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
184 // Called at taint-time.
173 public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) 185 public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
174 { 186 {
175 // The user moving a child around requires the rebuilding of the linkset compound shape 187 // The user moving a child around requires the rebuilding of the linkset compound shape
@@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset
182 && !physicalUpdate 194 && !physicalUpdate
183 && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) 195 && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
184 { 196 {
197 // TODO: replace this with are calculation of the child prim's orientation and pos.
185 updated.LinksetInfo = null; 198 updated.LinksetInfo = null;
186 ScheduleRebuild(updated); 199 ScheduleRebuild(updated);
187 } 200 }
@@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset
230 if (inTaintTime) 243 if (inTaintTime)
231 { 244 {
232 OMV.Vector3 oldPos = child.RawPosition; 245 OMV.Vector3 oldPos = child.RawPosition;
233 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; 246 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot;
234 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; 247 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
235 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", 248 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
236 child.LocalID, oldPos, lci, child.RawPosition); 249 child.LocalID, oldPos, lci, child.RawPosition);
@@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset
238 else 251 else
239 { 252 {
240 // TaintedObject is not used here so the raw position is set now and not at taint-time. 253 // TaintedObject is not used here so the raw position is set now and not at taint-time.
241 child.Position = LinksetRoot.RawPosition + lci.OffsetPos; 254 child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot;
242 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; 255 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
243 } 256 }
244 } 257 }
@@ -306,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset
306 // Constraint linksets are rebuilt every time. 319 // Constraint linksets are rebuilt every time.
307 // Note that this works for rebuilding just the root after a linkset is taken apart. 320 // Note that this works for rebuilding just the root after a linkset is taken apart.
308 // Called at taint time!! 321 // Called at taint time!!
322 private bool disableCOM = true; // disable until we get this debugged
309 private void RecomputeLinksetCompound() 323 private void RecomputeLinksetCompound()
310 { 324 {
311 try 325 try
@@ -316,10 +330,34 @@ public sealed class BSLinksetCompound : BSLinkset
316 // Cause the root shape to be rebuilt as a compound object with just the root in it 330 // Cause the root shape to be rebuilt as a compound object with just the root in it
317 LinksetRoot.ForceBodyShapeRebuild(true); 331 LinksetRoot.ForceBodyShapeRebuild(true);
318 332
333 // The center of mass for the linkset is the geometric center of the group.
334 // Compute a displacement for each component so it is relative to the center-of-mass.
335 // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
336 OMV.Vector3 centerOfMass;
337 OMV.Vector3 centerDisplacement = OMV.Vector3.Zero;
338 if (disableCOM) // DEBUG DEBUG
339 { // DEBUG DEBUG
340 centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
341 LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
342 } // DEBUG DEBUG
343 else
344 {
345 centerOfMass = ComputeLinksetGeometricCenter();
346 centerDisplacement = centerOfMass - LinksetRoot.RawPosition;
347
348 // Since we're displacing the center of the shape, we need to move the body in the world
349 LinksetRoot.PositionDisplacement = centerDisplacement;
350
351 PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
352 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
353 LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
354 }
355
319 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", 356 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
320 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); 357 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
321 358
322 // Add a shape for each of the other children in the linkset 359 // Add a shape for each of the other children in the linkset
360 int memberIndex = 1;
323 ForEachMember(delegate(BSPhysObject cPrim) 361 ForEachMember(delegate(BSPhysObject cPrim)
324 { 362 {
325 if (!IsRoot(cPrim)) 363 if (!IsRoot(cPrim))
@@ -331,19 +369,21 @@ public sealed class BSLinksetCompound : BSLinkset
331 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; 369 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
332 if (lci == null) 370 if (lci == null)
333 { 371 {
334 // Each child position and rotation is given relative to the root. 372 // Each child position and rotation is given relative to the center-of-mass.
335 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); 373 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
336 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; 374 OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
375 OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
337 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; 376 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
338 377
339 // Save relative position for recomputing child's world position after moving linkset. 378 // Save relative position for recomputing child's world position after moving linkset.
340 lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); 379 lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
380 lci.OffsetFromRoot = displacementFromRoot;
341 cPrim.LinksetInfo = lci; 381 cPrim.LinksetInfo = lci;
342 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); 382 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
343 } 383 }
344 384
345 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", 385 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
346 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 386 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
347 387
348 if (cPrim.PhysShape.isNativeShape) 388 if (cPrim.PhysShape.isNativeShape)
349 { 389 {
@@ -359,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset
359 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); 399 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
360 BulletShape newShape = cPrim.PhysShape; 400 BulletShape newShape = cPrim.PhysShape;
361 cPrim.PhysShape = saveShape; 401 cPrim.PhysShape = saveShape;
362 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); 402 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
363 } 403 }
364 else 404 else
365 { 405 {
@@ -371,8 +411,10 @@ public sealed class BSLinksetCompound : BSLinkset
371 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 411 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
372 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 412 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
373 } 413 }
374 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 414 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
375 } 415 }
416 lci.Index = memberIndex;
417 memberIndex++;
376 } 418 }
377 return false; // 'false' says to move onto the next child in the list 419 return false; // 'false' says to move onto the next child in the list
378 }); 420 });
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
80 public static float AvatarStepForceFactor { get; private set; } 80 public static float AvatarStepForceFactor { get; private set; }
81 81
82 public static float VehicleAngularDamping { get; private set; } 82 public static float VehicleAngularDamping { get; private set; }
83 public static float VehicleDebuggingEnabled { get; private set; }
83 84
84 public static float LinksetImplementation { get; private set; } 85 public static float LinksetImplementation { get; private set; }
85 public static float LinkConstraintUseFrameOffset { get; private set; } 86 public static float LinkConstraintUseFrameOffset { get; private set; }
@@ -427,6 +428,11 @@ public static class BSParam
427 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, 428 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
428 (s) => { return VehicleAngularDamping; }, 429 (s) => { return VehicleAngularDamping; },
429 (s,p,l,v) => { VehicleAngularDamping = v; } ), 430 (s,p,l,v) => { VehicleAngularDamping = v; } ),
431 new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
432 ConfigurationParameters.numericFalse,
433 (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
434 (s) => { return VehicleDebuggingEnabled; },
435 (s,p,l,v) => { VehicleDebuggingEnabled = v; } ),
430 436
431 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 437 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
432 0f, 438 0f,
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index e8575f6..821f470 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -73,6 +73,8 @@ public abstract class BSPhysObject : PhysicsActor
73 73
74 // A linkset of just me 74 // A linkset of just me
75 Linkset = BSLinkset.Factory(PhysicsScene, this); 75 Linkset = BSLinkset.Factory(PhysicsScene, this);
76 PositionDisplacement = OMV.Vector3.Zero;
77
76 LastAssetBuildFailed = false; 78 LastAssetBuildFailed = false;
77 79
78 // Default material type 80 // Default material type
@@ -135,6 +137,7 @@ public abstract class BSPhysObject : PhysicsActor
135 public virtual OMV.Vector3 Scale { get; set; } 137 public virtual OMV.Vector3 Scale { get; set; }
136 public abstract bool IsSolid { get; } 138 public abstract bool IsSolid { get; }
137 public abstract bool IsStatic { get; } 139 public abstract bool IsStatic { get; }
140 public abstract bool IsSelected { get; }
138 141
139 // Materialness 142 // Materialness
140 public MaterialAttributes.Material Material { get; private set; } 143 public MaterialAttributes.Material Material { get; private set; }
@@ -156,6 +159,14 @@ public abstract class BSPhysObject : PhysicsActor
156 public abstract OMV.Vector3 RawPosition { get; set; } 159 public abstract OMV.Vector3 RawPosition { get; set; }
157 public abstract OMV.Vector3 ForcePosition { get; set; } 160 public abstract OMV.Vector3 ForcePosition { get; set; }
158 161
162 // Position is what the simulator thinks the positions of the prim is.
163 // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
164 // sometimes it is necessary to displace the position the physics engine thinks
165 // the position is. PositionDisplacement must be added and removed from the
166 // position as the simulator position is stored and fetched from the physics
167 // engine.
168 public virtual OMV.Vector3 PositionDisplacement { get; set; }
169
159 public abstract OMV.Quaternion RawOrientation { get; set; } 170 public abstract OMV.Quaternion RawOrientation { get; set; }
160 public abstract OMV.Quaternion ForceOrientation { get; set; } 171 public abstract OMV.Quaternion ForceOrientation { get; set; }
161 172
@@ -371,10 +382,13 @@ public abstract class BSPhysObject : PhysicsActor
371 { 382 {
372 string identifier = op + "-" + id.ToString(); 383 string identifier = op + "-" + id.ToString();
373 384
374 // Clean out any existing action 385 lock (RegisteredActions)
375 UnRegisterPreStepAction(op, id); 386 {
387 // Clean out any existing action
388 UnRegisterPreStepAction(op, id);
376 389
377 RegisteredActions[identifier] = actn; 390 RegisteredActions[identifier] = actn;
391 }
378 PhysicsScene.BeforeStep += actn; 392 PhysicsScene.BeforeStep += actn;
379 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); 393 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
380 } 394 }
@@ -384,22 +398,28 @@ public abstract class BSPhysObject : PhysicsActor
384 { 398 {
385 string identifier = op + "-" + id.ToString(); 399 string identifier = op + "-" + id.ToString();
386 bool removed = false; 400 bool removed = false;
387 if (RegisteredActions.ContainsKey(identifier)) 401 lock (RegisteredActions)
388 { 402 {
389 PhysicsScene.BeforeStep -= RegisteredActions[identifier]; 403 if (RegisteredActions.ContainsKey(identifier))
390 RegisteredActions.Remove(identifier); 404 {
391 removed = true; 405 PhysicsScene.BeforeStep -= RegisteredActions[identifier];
406 RegisteredActions.Remove(identifier);
407 removed = true;
408 }
392 } 409 }
393 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); 410 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
394 } 411 }
395 412
396 protected void UnRegisterAllPreStepActions() 413 protected void UnRegisterAllPreStepActions()
397 { 414 {
398 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions) 415 lock (RegisteredActions)
399 { 416 {
400 PhysicsScene.BeforeStep -= kvp.Value; 417 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions)
418 {
419 PhysicsScene.BeforeStep -= kvp.Value;
420 }
421 RegisteredActions.Clear();
401 } 422 }
402 RegisteredActions.Clear();
403 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); 423 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
404 } 424 }
405 425
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
59 { 59 {
60 if (_mScene == null) 60 if (_mScene == null)
61 { 61 {
62 _mScene = new BSScene(sceneIdentifier); 62 _mScene = new BSScene(GetName(), sceneIdentifier);
63 } 63 }
64 return (_mScene); 64 return (_mScene);
65 } 65 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 400d5d6..79fe632 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject
50 private bool _grabbed; 50 private bool _grabbed;
51 private bool _isSelected; 51 private bool _isSelected;
52 private bool _isVolumeDetect; 52 private bool _isVolumeDetect;
53
54 // _position is what the simulator thinks the positions of the prim is.
53 private OMV.Vector3 _position; 55 private OMV.Vector3 _position;
56
54 private float _mass; // the mass of this object 57 private float _mass; // the mass of this object
55 private float _density; 58 private float _density;
56 private OMV.Vector3 _force; 59 private OMV.Vector3 _force;
@@ -169,6 +172,7 @@ public sealed class BSPrim : BSPhysObject
169 public override PrimitiveBaseShape Shape { 172 public override PrimitiveBaseShape Shape {
170 set { 173 set {
171 BaseShape = value; 174 BaseShape = value;
175 LastAssetBuildFailed = false;
172 ForceBodyShapeRebuild(false); 176 ForceBodyShapeRebuild(false);
173 } 177 }
174 } 178 }
@@ -178,7 +182,6 @@ public sealed class BSPrim : BSPhysObject
178 182
179 public override bool ForceBodyShapeRebuild(bool inTaintTime) 183 public override bool ForceBodyShapeRebuild(bool inTaintTime)
180 { 184 {
181 LastAssetBuildFailed = false;
182 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() 185 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
183 { 186 {
184 _mass = CalculateMass(); // changing the shape changes the mass 187 _mass = CalculateMass(); // changing the shape changes the mass
@@ -204,6 +207,10 @@ public sealed class BSPrim : BSPhysObject
204 } 207 }
205 } 208 }
206 } 209 }
210 public override bool IsSelected
211 {
212 get { return _isSelected; }
213 }
207 public override void CrossingFailure() { return; } 214 public override void CrossingFailure() { return; }
208 215
209 // link me to the specified parent 216 // link me to the specified parent
@@ -290,7 +297,7 @@ public sealed class BSPrim : BSPhysObject
290 */ 297 */
291 298
292 // don't do the GetObjectPosition for root elements because this function is called a zillion times. 299 // don't do the GetObjectPosition for root elements because this function is called a zillion times.
293 // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); 300 // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement;
294 return _position; 301 return _position;
295 } 302 }
296 set { 303 set {
@@ -316,18 +323,37 @@ public sealed class BSPrim : BSPhysObject
316 } 323 }
317 public override OMV.Vector3 ForcePosition { 324 public override OMV.Vector3 ForcePosition {
318 get { 325 get {
319 _position = PhysicsScene.PE.GetPosition(PhysBody); 326 _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement;
320 return _position; 327 return _position;
321 } 328 }
322 set { 329 set {
323 _position = value; 330 _position = value;
324 if (PhysBody.HasPhysicalBody) 331 if (PhysBody.HasPhysicalBody)
325 { 332 {
326 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 333 PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
327 ActivateIfPhysical(false); 334 ActivateIfPhysical(false);
328 } 335 }
329 } 336 }
330 } 337 }
338 // Override to have position displacement immediately update the physical position.
339 // A feeble attempt to keep the sim and physical positions in sync
340 // Must be called at taint time.
341 public override OMV.Vector3 PositionDisplacement
342 {
343 get
344 {
345 return base.PositionDisplacement;
346 }
347 set
348 {
349 base.PositionDisplacement = value;
350 PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate()
351 {
352 if (PhysBody.HasPhysicalBody)
353 PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation);
354 });
355 }
356 }
331 357
332 // Check that the current position is sane and, if not, modify the position to make it so. 358 // Check that the current position is sane and, if not, modify the position to make it so.
333 // Check for being below terrain and being out of bounds. 359 // Check for being below terrain and being out of bounds.
@@ -336,7 +362,7 @@ public sealed class BSPrim : BSPhysObject
336 { 362 {
337 bool ret = false; 363 bool ret = false;
338 364
339 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) 365 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
340 { 366 {
341 // The physical object is out of the known/simulated area. 367 // The physical object is out of the known/simulated area.
342 // Upper levels of code will handle the transition to other areas so, for 368 // Upper levels of code will handle the transition to other areas so, for
@@ -350,8 +376,11 @@ public sealed class BSPrim : BSPhysObject
350 { 376 {
351 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 377 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
352 float targetHeight = terrainHeight + (Size.Z / 2f); 378 float targetHeight = terrainHeight + (Size.Z / 2f);
353 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. 379 // If the object is below ground it just has to be moved up because pushing will
354 upForce.Z = (terrainHeight - RawPosition.Z) * 1f; 380 // not get it through the terrain
381 _position.Z = targetHeight;
382 if (inTaintTime)
383 ForcePosition = _position;
355 ret = true; 384 ret = true;
356 } 385 }
357 386
@@ -363,20 +392,15 @@ public sealed class BSPrim : BSPhysObject
363 { 392 {
364 // Upforce proportional to the distance away from the water. Correct the error in 1 sec. 393 // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
365 upForce.Z = (waterHeight - RawPosition.Z) * 1f; 394 upForce.Z = (waterHeight - RawPosition.Z) * 1f;
395
396 // Apply upforce and overcome gravity.
397 OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
398 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
399 AddForce(correctionForce, false, inTaintTime);
366 ret = true; 400 ret = true;
367 } 401 }
368 } 402 }
369 403
370 // The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
371 // TODO: This should be intergrated with a geneal physics action mechanism.
372 // TODO: This should be moderated with PID'ness.
373 if (ret)
374 {
375 // Apply upforce and overcome gravity.
376 OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
377 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
378 AddForce(correctionForce, false, inTaintTime);
379 }
380 return ret; 404 return ret;
381 } 405 }
382 406
@@ -410,7 +434,7 @@ public sealed class BSPrim : BSPhysObject
410 } 434 }
411 else 435 else
412 { 436 {
413 OMV.Vector3 grav = ComputeGravity(); 437 OMV.Vector3 grav = ComputeGravity(Buoyancy);
414 438
415 if (inWorld) 439 if (inWorld)
416 { 440 {
@@ -445,12 +469,12 @@ public sealed class BSPrim : BSPhysObject
445 } 469 }
446 470
447 // Return what gravity should be set to this very moment 471 // Return what gravity should be set to this very moment
448 private OMV.Vector3 ComputeGravity() 472 public OMV.Vector3 ComputeGravity(float buoyancy)
449 { 473 {
450 OMV.Vector3 ret = PhysicsScene.DefaultGravity; 474 OMV.Vector3 ret = PhysicsScene.DefaultGravity;
451 475
452 if (!IsStatic) 476 if (!IsStatic)
453 ret *= (1f - Buoyancy); 477 ret *= (1f - buoyancy);
454 478
455 return ret; 479 return ret;
456 } 480 }
@@ -586,6 +610,7 @@ public sealed class BSPrim : BSPhysObject
586 _velocity = value; 610 _velocity = value;
587 if (PhysBody.HasPhysicalBody) 611 if (PhysBody.HasPhysicalBody)
588 { 612 {
613 DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity);
589 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); 614 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
590 ActivateIfPhysical(false); 615 ActivateIfPhysical(false);
591 } 616 }
@@ -650,12 +675,7 @@ public sealed class BSPrim : BSPhysObject
650 675
651 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() 676 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
652 { 677 {
653 if (PhysBody.HasPhysicalBody) 678 ForceOrientation = _orientation;
654 {
655 // _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody);
656 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
657 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
658 }
659 }); 679 });
660 } 680 }
661 } 681 }
@@ -670,7 +690,8 @@ public sealed class BSPrim : BSPhysObject
670 set 690 set
671 { 691 {
672 _orientation = value; 692 _orientation = value;
673 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 693 if (PhysBody.HasPhysicalBody)
694 PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
674 } 695 }
675 } 696 }
676 public override int PhysicsActorType { 697 public override int PhysicsActorType {
@@ -809,7 +830,7 @@ public sealed class BSPrim : BSPhysObject
809 // PhysicsScene.PE.ClearAllForces(BSBody); 830 // PhysicsScene.PE.ClearAllForces(BSBody);
810 831
811 // For good measure, make sure the transform is set through to the motion state 832 // For good measure, make sure the transform is set through to the motion state
812 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 833 PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
813 834
814 // Center of mass is at the center of the object 835 // Center of mass is at the center of the object
815 // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); 836 // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
@@ -1153,33 +1174,70 @@ public sealed class BSPrim : BSPhysObject
1153 // This added force will only last the next simulation tick. 1174 // This added force will only last the next simulation tick.
1154 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 1175 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
1155 // for an object, doesn't matter if force is a pushforce or not 1176 // for an object, doesn't matter if force is a pushforce or not
1156 if (!IsStatic && force.IsFinite()) 1177 if (!IsStatic)
1157 { 1178 {
1158 float magnitude = force.Length(); 1179 if (force.IsFinite())
1159 if (magnitude > BSParam.MaxAddForceMagnitude)
1160 { 1180 {
1161 // Force has a limit 1181 float magnitude = force.Length();
1162 force = force / magnitude * BSParam.MaxAddForceMagnitude; 1182 if (magnitude > BSParam.MaxAddForceMagnitude)
1163 } 1183 {
1184 // Force has a limit
1185 force = force / magnitude * BSParam.MaxAddForceMagnitude;
1186 }
1164 1187
1165 OMV.Vector3 addForce = force; 1188 OMV.Vector3 addForce = force;
1166 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); 1189 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
1167 1190
1168 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() 1191 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
1169 {
1170 // Bullet adds this central force to the total force for this tick
1171 DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
1172 if (PhysBody.HasPhysicalBody)
1173 { 1192 {
1174 PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); 1193 // Bullet adds this central force to the total force for this tick
1175 ActivateIfPhysical(false); 1194 DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
1176 } 1195 if (PhysBody.HasPhysicalBody)
1177 }); 1196 {
1197 PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
1198 ActivateIfPhysical(false);
1199 }
1200 });
1201 }
1202 else
1203 {
1204 m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
1205 return;
1206 }
1178 } 1207 }
1179 else 1208 }
1209
1210 public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) {
1211 // for an object, doesn't matter if force is a pushforce or not
1212 if (!IsStatic)
1180 { 1213 {
1181 m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); 1214 if (impulse.IsFinite())
1182 return; 1215 {
1216 float magnitude = impulse.Length();
1217 if (magnitude > BSParam.MaxAddForceMagnitude)
1218 {
1219 // Force has a limit
1220 impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude;
1221 }
1222
1223 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
1224 OMV.Vector3 addImpulse = impulse;
1225 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate()
1226 {
1227 // Bullet adds this impulse immediately to the velocity
1228 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
1229 if (PhysBody.HasPhysicalBody)
1230 {
1231 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse);
1232 ActivateIfPhysical(false);
1233 }
1234 });
1235 }
1236 else
1237 {
1238 m_log.WarnFormat("{0}: AddForceImpulse: Got a NaN impulse applied to a prim. LocalID={1}", LogHeader, LocalID);
1239 return;
1240 }
1183 } 1241 }
1184 } 1242 }
1185 1243
@@ -1561,21 +1619,6 @@ public sealed class BSPrim : BSPhysObject
1561 1619
1562 // The physics engine says that properties have updated. Update same and inform 1620 // The physics engine says that properties have updated. Update same and inform
1563 // the world that things have changed. 1621 // the world that things have changed.
1564 // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate()
1565 enum UpdatedProperties {
1566 Position = 1 << 0,
1567 Rotation = 1 << 1,
1568 Velocity = 1 << 2,
1569 Acceleration = 1 << 3,
1570 RotationalVel = 1 << 4
1571 }
1572
1573 const float ROTATION_TOLERANCE = 0.01f;
1574 const float VELOCITY_TOLERANCE = 0.001f;
1575 const float POSITION_TOLERANCE = 0.05f;
1576 const float ACCELERATION_TOLERANCE = 0.01f;
1577 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1578
1579 public override void UpdateProperties(EntityProperties entprop) 1622 public override void UpdateProperties(EntityProperties entprop)
1580 { 1623 {
1581 // Updates only for individual prims and for the root object of a linkset. 1624 // Updates only for individual prims and for the root object of a linkset.
@@ -1588,7 +1631,8 @@ public sealed class BSPrim : BSPhysObject
1588 entprop.RotationalVelocity = OMV.Vector3.Zero; 1631 entprop.RotationalVelocity = OMV.Vector3.Zero;
1589 } 1632 }
1590 1633
1591 // Assign directly to the local variables so the normal set action does not happen 1634 // Assign directly to the local variables so the normal set actions do not happen
1635 entprop.Position -= PositionDisplacement;
1592 _position = entprop.Position; 1636 _position = entprop.Position;
1593 _orientation = entprop.Rotation; 1637 _orientation = entprop.Rotation;
1594 _velocity = entprop.Velocity; 1638 _velocity = entprop.Velocity;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7017194..e0b4992 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
167 public bool VehiclePhysicalLoggingEnabled { get; private set; } 167 public bool VehiclePhysicalLoggingEnabled { get; private set; }
168 168
169 #region Construction and Initialization 169 #region Construction and Initialization
170 public BSScene(string identifier) 170 public BSScene(string engineType, string identifier)
171 { 171 {
172 m_initialized = false; 172 m_initialized = false;
173 // we are passed the name of the region we're working for. 173
174 // The name of the region we're working for is passed to us. Keep for identification.
174 RegionName = identifier; 175 RegionName = identifier;
176
177 // Set identifying variables in the PhysicsScene interface.
178 EngineType = engineType;
179 Name = EngineType + "/" + RegionName;
175 } 180 }
176 181
177 public override void Initialise(IMesher meshmerizer, IConfigSource config) 182 public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -382,12 +387,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
382 if (!m_initialized) return null; 387 if (!m_initialized) return null;
383 388
384 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 389 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
385 lock (PhysObjects) PhysObjects.Add(localID, actor); 390 lock (PhysObjects)
391 PhysObjects.Add(localID, actor);
386 392
387 // TODO: Remove kludge someday. 393 // TODO: Remove kludge someday.
388 // We must generate a collision for avatars whether they collide or not. 394 // We must generate a collision for avatars whether they collide or not.
389 // This is required by OpenSim to update avatar animations, etc. 395 // This is required by OpenSim to update avatar animations, etc.
390 lock (m_avatars) m_avatars.Add(actor); 396 lock (m_avatars)
397 m_avatars.Add(actor);
391 398
392 return actor; 399 return actor;
393 } 400 }
@@ -403,9 +410,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
403 { 410 {
404 try 411 try
405 { 412 {
406 lock (PhysObjects) PhysObjects.Remove(actor.LocalID); 413 lock (PhysObjects)
414 PhysObjects.Remove(bsactor.LocalID);
407 // Remove kludge someday 415 // Remove kludge someday
408 lock (m_avatars) m_avatars.Remove(bsactor); 416 lock (m_avatars)
417 m_avatars.Remove(bsactor);
409 } 418 }
410 catch (Exception e) 419 catch (Exception e)
411 { 420 {
@@ -414,6 +423,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
414 bsactor.Destroy(); 423 bsactor.Destroy();
415 // bsactor.dispose(); 424 // bsactor.dispose();
416 } 425 }
426 else
427 {
428 m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}",
429 LogHeader, actor.LocalID, actor.GetType().Name);
430 }
417 } 431 }
418 432
419 public override void RemovePrim(PhysicsActor prim) 433 public override void RemovePrim(PhysicsActor prim)
@@ -486,6 +500,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
486 ProcessTaints(); 500 ProcessTaints();
487 501
488 // Some of the physical objects requre individual, pre-step calls 502 // Some of the physical objects requre individual, pre-step calls
503 // (vehicles and avatar movement, in particular)
489 TriggerPreStepEvent(timeStep); 504 TriggerPreStepEvent(timeStep);
490 505
491 // the prestep actions might have added taints 506 // the prestep actions might have added taints
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
906 } 906 }
907 } 907 }
908 908
909 // While we figure out the real problem, stick a simple native shape on the object. 909 // While we figure out the real problem, stick in a simple box for the object.
910 BulletShape fillinShape = 910 BulletShape fillinShape =
911 BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); 911 BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
912 912
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 29bd4e4..59cbab9 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,12 +1,17 @@
1CURRENT PRIORITIES 1CURRENT PRIORITIES
2================================================= 2=================================================
3Nebadon vehicles turning funny in arena
4limitMotorUp calibration (more down?)
5Vehicle angular vertical attraction
6Vehicle angular deflection
7 Preferred orientation angular correction fix
8vehicle angular banking
3Avatars walking up stairs (HALF DONE) 9Avatars walking up stairs (HALF DONE)
10 Radius of the capsule affects ability to climb edges.
4Vehicle movement on terrain smoothness 11Vehicle movement on terrain smoothness
5limitMotorUp calibration (more down?)
6Preferred orientation angular correction fix
7Surfboard go wonky when turning 12Surfboard go wonky when turning
8 Angular motor direction is global coordinates rather than local coordinates? 13 Angular motor direction is global coordinates rather than local coordinates?
9Boats float low in the water 14Boats float low in the water (DONE)
10Avatar movement 15Avatar movement
11 flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) 16 flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
12 walking up stairs is not calibrated correctly (stairs out of Kepler cabin) 17 walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
@@ -33,19 +38,15 @@ CRASHES
33 38
34VEHICLES TODO LIST: 39VEHICLES TODO LIST:
35================================================= 40=================================================
36Angular motor direction is global coordinates rather than local coordinates
37Border crossing with linked vehicle causes crash 41Border crossing with linked vehicle causes crash
38Vehicles (Move smoothly) 42Vehicles (Move smoothly)
39Add vehicle collisions so IsColliding is properly reported.
40 Needed for banking, limitMotorUp, movementLimiting, ...
41VehicleAddForce is not scaled by the simulation step but it is only
42 applied for one step. Should it be scaled?
43Some vehicles should not be able to turn if no speed or off ground. 43Some vehicles should not be able to turn if no speed or off ground.
44Cannot edit/move a vehicle being ridden: it jumps back to the origional position. 44Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
45Neb car jiggling left and right 45Neb car jiggling left and right
46 Happens on terrain and any other mesh object. Flat cubes are much smoother. 46 Happens on terrain and any other mesh object. Flat cubes are much smoother.
47 This has been reduced but not eliminated. 47 This has been reduced but not eliminated.
48Implement referenceFrame for all the motion routines. 48Implement referenceFrame for all the motion routines.
49For limitMotorUp, use raycast down to find if vehicle is in the air.
49Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. 50Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
50 Verify that angular motion specified around Z moves in the vehicle coordinates. 51 Verify that angular motion specified around Z moves in the vehicle coordinates.
51Verify llGetVel() is returning a smooth and good value for vehicle movement. 52Verify llGetVel() is returning a smooth and good value for vehicle movement.
@@ -54,14 +55,13 @@ Implement function efficiency for lineaar and angular motion.
54After getting off a vehicle, the root prim is phantom (can be walked through) 55After getting off a vehicle, the root prim is phantom (can be walked through)
55 Need to force a position update for the root prim after compound shape destruction 56 Need to force a position update for the root prim after compound shape destruction
56Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) 57Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
57For limitMotorUp, use raycast down to find if vehicle is in the air.
58Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). 58Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties().
59 A kludge that isn't fixing the real problem of Bullet adding extra motion. 59 A kludge that isn't fixing the real problem of Bullet adding extra motion.
60Incorporate inter-relationship of angular corrections. For instance, angularDeflection 60Incorporate inter-relationship of angular corrections. For instance, angularDeflection
61 and angularMotorUp will compute same X or Y correction. When added together 61 and angularMotorUp will compute same X or Y correction. When added together
62 creates over-correction and over-shoot and wabbling. 62 creates over-correction and over-shoot and wabbling.
63 63
64BULLETSIM TODO LIST: 64GENERAL TODO LIST:
65================================================= 65=================================================
66Implement an avatar mesh shape. The Bullet capsule is way too limited. 66Implement an avatar mesh shape. The Bullet capsule is way too limited.
67 Consider just hand creating a vertex/index array in a new BSShapeAvatar. 67 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
121Verify/think through scripts in children of linksets. What do they reference 121Verify/think through scripts in children of linksets. What do they reference
122 and return when getting position, velocity, ... 122 and return when getting position, velocity, ...
123Confirm constraint linksets still work after making all the changes for compound linksets. 123Confirm constraint linksets still work after making all the changes for compound linksets.
124Use PostTaint callback to do rebuilds for constraint linksets to reduce rebuilding
124Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. 125Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt.
125 For compound linksets, add ability to remove or reposition individual child shapes. 126 For compound linksets, add ability to remove or reposition individual child shapes.
126Disable activity of passive linkset children.
127 Since the linkset is a compound object, the old prims are left lying
128 around and need to be phantomized so they don't collide, ...
129Speed up creation of large physical linksets 127Speed up creation of large physical linksets
130 For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. 128 For instance, sitting in Neb's car (130 prims) takes several seconds to become physical.
131 REALLY bad for very large physical linksets (freezes the sim for many seconds). 129 REALLY bad for very large physical linksets (freezes the sim for many seconds).
@@ -138,25 +136,21 @@ MORE
138Use the HACD convex hull routine in Bullet rather than the C# version. 136Use the HACD convex hull routine in Bullet rather than the C# version.
139Do we need to do convex hulls all the time? Can complex meshes be left meshes? 137Do we need to do convex hulls all the time? Can complex meshes be left meshes?
140 There is some problem with meshes and collisions 138 There is some problem with meshes and collisions
141Test avatar walking up stairs. How does compare with SL. 139 Hulls are not as detailed as meshes. Hulled vehicles insides are different shape.
142 Radius of the capsule affects ability to climb edges.
143Debounce avatar contact so legs don't keep folding up when standing. 140Debounce avatar contact so legs don't keep folding up when standing.
144Implement LSL physics controls. Like STATUS_ROTATE_X. 141Implement LSL physics controls. Like STATUS_ROTATE_X.
145Add border extensions to terrain to help region crossings and objects leaving region. 142Add border extensions to terrain to help region crossings and objects leaving region.
146Use a different capsule shape for avatar when sitting 143Use a different capsule shape for avatar when sitting
147 LL uses a pyrimidal shape scaled by the avatar's bounding box 144 LL uses a pyrimidal shape scaled by the avatar's bounding box
148 http://wiki.secondlife.com/wiki/File:Avmeshforms.png 145 http://wiki.secondlife.com/wiki/File:Avmeshforms.png
149
150Performance test with lots of avatars. Can BulletSim support a thousand? 146Performance test with lots of avatars. Can BulletSim support a thousand?
151Optimize collisions in C++: only send up to the object subscribed to collisions. 147Optimize collisions in C++: only send up to the object subscribed to collisions.
152 Use collision subscription and remove the collsion(A,B) and collision(B,A) 148 Use collision subscription and remove the collsion(A,B) and collision(B,A)
153Check whether SimMotionState needs large if statement (see TODO). 149Check whether SimMotionState needs large if statement (see TODO).
154
155Implement 'top colliders' info. 150Implement 'top colliders' info.
156Avatar jump 151Avatar jump
157Performance measurement and changes to make quicker. 152Performance measurement and changes to make quicker.
158Implement detailed physics stats (GetStats()). 153Implement detailed physics stats (GetStats()).
159
160Measure performance improvement from hulls 154Measure performance improvement from hulls
161Test not using ghost objects for volume detect implementation. 155Test not using ghost objects for volume detect implementation.
162Performance of closures and delegates for taint processing 156Performance of closures and delegates for taint processing
@@ -164,9 +158,7 @@ Performance of closures and delegates for taint processing
164 Is any slowdown introduced by the existing implementation significant? 158 Is any slowdown introduced by the existing implementation significant?
165Is there are more efficient method of implementing pre and post step actions? 159Is there are more efficient method of implementing pre and post step actions?
166 See http://www.codeproject.com/Articles/29922/Weak-Events-in-C 160 See http://www.codeproject.com/Articles/29922/Weak-Events-in-C
167
168Physics Arena central pyramid: why is one side permiable? 161Physics Arena central pyramid: why is one side permiable?
169
170In SL, perfect spheres don't seem to have rolling friction. Add special case. 162In SL, perfect spheres don't seem to have rolling friction. Add special case.
171Enforce physical parameter min/max: 163Enforce physical parameter min/max:
172 Gravity: [-1, 28] 164 Gravity: [-1, 28]
@@ -178,6 +170,8 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179
178 170
179INTERNAL IMPROVEMENT/CLEANUP 171INTERNAL IMPROVEMENT/CLEANUP
180================================================= 172=================================================
173Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to
174 BSScene.TaintedObject() could immediately execute the callback if already in taint time.
181Create the physical wrapper classes (BulletBody, BulletShape) by methods on 175Create the physical wrapper classes (BulletBody, BulletShape) by methods on
182 BSAPITemplate and make their actual implementation Bullet engine specific. 176 BSAPITemplate and make their actual implementation Bullet engine specific.
183 For the short term, just call the existing functions in ShapeCollection. 177 For the short term, just call the existing functions in ShapeCollection.
@@ -197,22 +191,19 @@ Generalize Dynamics and PID with standardized motors.
197Generalize Linkset and vehicles into PropertyManagers 191Generalize Linkset and vehicles into PropertyManagers
198 Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies 192 Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
199 Potentially add events for shape destruction, etc. 193 Potentially add events for shape destruction, etc.
200Complete implemention of preStepActions 194Better mechanism for resetting linkset set and vehicle parameters when body rebuilt.
201 Replace vehicle step call with prestep event. 195 BSPrim.CreateGeomAndObject is kludgy with the callbacks, etc.
202 Is there a need for postStepActions? postStepTaints?
203Implement linkset by setting position of children when root updated. (LinksetManual) 196Implement linkset by setting position of children when root updated. (LinksetManual)
204 Linkset implementation using manual prim movement. 197 Linkset implementation using manual prim movement.
205LinkablePrim class? Would that simplify/centralize the linkset logic? 198LinkablePrim class? Would that simplify/centralize the linkset logic?
206BSScene.UpdateParameterSet() is broken. How to set params on objects? 199BSScene.UpdateParameterSet() is broken. How to set params on objects?
207Remove HeightmapInfo from terrain specification
208 Since C++ code does not need terrain height, this structure et al are not needed.
209Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will 200Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
210 bob at the water level. BSPrim.PositionSanityCheck(). 201 bob at the water level. BSPrim.PositionSanityCheck()
211Should taints check for existance or activeness of target? 202Should taints check for existance or activeness of target?
212 When destroying linksets/etc, taints can be generated for objects that are 203 When destroying linksets/etc, taints can be generated for objects that are
213 actually gone when the taint happens. Crashes don't happen because the taint closure 204 actually gone when the taint happens. Crashes don't happen because the taint closure
214 keeps the object from being freed, but that is just an accident. 205 keeps the object from being freed, but that is just an accident.
215 Possibly have and 'active' flag that is checked by the taint processor? 206 Possibly have an 'active' flag that is checked by the taint processor?
216Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) 207Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones)
217Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? 208Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'?
218There are TOO MANY interfaces from BulletSim core to Bullet itself 209There are TOO MANY interfaces from BulletSim core to Bullet itself
@@ -282,3 +273,18 @@ Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE)
282Meshes rendering as bounding boxes (DONE) 273Meshes rendering as bounding boxes (DONE)
283 (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box) 274 (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box)
284llMoveToTarget (Resolution: added simple motor to update the position.) 275llMoveToTarget (Resolution: added simple motor to update the position.)
276Angular motor direction is global coordinates rather than local coordinates (DONE)
277Add vehicle collisions so IsColliding is properly reported. (DONE)
278 Needed for banking, limitMotorUp, movementLimiting, ...
279 (Resolution: added CollisionFlags.BS_VEHICLE_COLLISION and code to use it)
280VehicleAddForce is not scaled by the simulation step but it is only
281 applied for one step. Should it be scaled? (DONE)
282 (Resolution: use force for timed things, Impulse for immediate, non-timed things)
283Complete implemention of preStepActions (DONE)
284 Replace vehicle step call with prestep event.
285 Is there a need for postStepActions? postStepTaints?
286Disable activity of passive linkset children. (DONE)
287 Since the linkset is a compound object, the old prims are left lying
288 around and need to be phantomized so they don't collide, ...
289Remove HeightmapInfo from terrain specification (DONE)
290 Since C++ code does not need terrain height, this structure et al are not needed. \ No newline at end of file
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
62// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 62// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 63
64 /// <summary> 64 /// <summary>
65 /// Name of this scene. Useful in debug messages to distinguish one OdeScene instance from another. 65 /// A unique identifying string for this instance of the physics engine.
66 /// Useful in debug messages to distinguish one OdeScene instance from another.
67 /// Usually set to include the region name that the physics engine is acting for.
66 /// </summary> 68 /// </summary>
67 public string Name { get; protected set; } 69 public string Name { get; protected set; }
68 70
71 /// <summary>
72 /// A string identifying the family of this physics engine. Most common values returned
73 /// are "OpenDynamicsEngine" and "BulletSim" but others are possible.
74 /// </summary>
75 public string EngineType { get; protected set; }
76
69 // The only thing that should register for this event is the SceneGraph 77 // The only thing that should register for this event is the SceneGraph
70 // Anything else could cause problems. 78 // Anything else could cause problems.
71
72 public event physicsCrash OnPhysicsCrash; 79 public event physicsCrash OnPhysicsCrash;
73 80
74 public static PhysicsScene Null 81 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
72 // http://opensimulator.org/mantis/view.php?id=2750). 72 // http://opensimulator.org/mantis/view.php?id=2750).
73 d.InitODE(); 73 d.InitODE();
74 74
75 m_scene = new OdeScene(sceneIdentifier); 75 m_scene = new OdeScene(GetName(), sceneIdentifier);
76 } 76 }
77 77
78 return m_scene; 78 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
526 /// These settings need to be tweaked 'exactly' right or weird stuff happens. 526 /// These settings need to be tweaked 'exactly' right or weird stuff happens.
527 /// </summary> 527 /// </summary>
528 /// <param value="name">Name of the scene. Useful in debug messages.</param> 528 /// <param value="name">Name of the scene. Useful in debug messages.</param>
529 public OdeScene(string name) 529 public OdeScene(string engineType, string name)
530 { 530 {
531 m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name); 531 m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name);
532 532
533 Name = name; 533 Name = name;
534 EngineType = engineType;
534 535
535 nearCallback = near; 536 nearCallback = near;
536 triCallback = TriCallback; 537 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
49 49
50 public PhysicsScene GetScene(string sceneIdentifier) 50 public PhysicsScene GetScene(string sceneIdentifier)
51 { 51 {
52 return new POSScene(sceneIdentifier); 52 return new POSScene(GetName(), sceneIdentifier);
53 } 53 }
54 54
55 public string GetName() 55 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
43 43
44 //protected internal string sceneIdentifier; 44 //protected internal string sceneIdentifier;
45 45
46 public POSScene(String _sceneIdentifier) 46 public POSScene(string engineType, String _sceneIdentifier)
47 { 47 {
48 EngineType = engineType;
49 Name = EngineType + "/" + _sceneIdentifier;
48 //sceneIdentifier = _sceneIdentifier; 50 //sceneIdentifier = _sceneIdentifier;
49 } 51 }
50 52
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
245 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 245 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
246 } 246 }
247 247
248 // Returns of the function is allowed. Throws a script exception if not allowed.
248 public void CheckThreatLevel(ThreatLevel level, string function) 249 public void CheckThreatLevel(ThreatLevel level, string function)
249 { 250 {
250 if (!m_OSFunctionsEnabled) 251 if (!m_OSFunctionsEnabled)
251 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws 252 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws
252 253
254 string reasonWhyNot = CheckThreatLevelTest(level, function);
255 if (!String.IsNullOrEmpty(reasonWhyNot))
256 {
257 OSSLError(reasonWhyNot);
258 }
259 }
260
261 // Check to see if function is allowed. Returns an empty string if function permitted
262 // or a string explaining why this function can't be used.
263 private string CheckThreatLevelTest(ThreatLevel level, string function)
264 {
253 if (!m_FunctionPerms.ContainsKey(function)) 265 if (!m_FunctionPerms.ContainsKey(function))
254 { 266 {
255 FunctionPerms perms = new FunctionPerms(); 267 FunctionPerms perms = new FunctionPerms();
@@ -329,10 +341,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 341 {
330 // Allow / disallow by threat level 342 // Allow / disallow by threat level
331 if (level > m_MaxThreatLevel) 343 if (level > m_MaxThreatLevel)
332 OSSLError( 344 return
333 String.Format( 345 String.Format(
334 "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.", 346 "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.",
335 function, m_MaxThreatLevel, level)); 347 function, m_MaxThreatLevel, level);
336 } 348 }
337 else 349 else
338 { 350 {
@@ -342,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
342 if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) 354 if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID))
343 { 355 {
344 // prim owner is in the list of allowed owners 356 // prim owner is in the list of allowed owners
345 return; 357 return String.Empty;
346 } 358 }
347 359
348 UUID ownerID = m_item.OwnerID; 360 UUID ownerID = m_item.OwnerID;
@@ -354,7 +366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
354 366
355 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) 367 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
356 { 368 {
357 return; 369 return String.Empty;
358 } 370 }
359 } 371 }
360 372
@@ -365,7 +377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
365 377
366 if (land.LandData.OwnerID == ownerID) 378 if (land.LandData.OwnerID == ownerID)
367 { 379 {
368 return; 380 return String.Empty;
369 } 381 }
370 } 382 }
371 383
@@ -375,7 +387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
375 //Only Estate Managers may use the function 387 //Only Estate Managers may use the function
376 if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) 388 if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
377 { 389 {
378 return; 390 return String.Empty;
379 } 391 }
380 } 392 }
381 393
@@ -384,25 +396,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 { 396 {
385 if (World.RegionInfo.EstateSettings.EstateOwner == ownerID) 397 if (World.RegionInfo.EstateSettings.EstateOwner == ownerID)
386 { 398 {
387 return; 399 return String.Empty;
388 } 400 }
389 } 401 }
390 402
391 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) 403 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
392 OSSLError( 404 return(
393 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.", 405 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.",
394 function)); 406 function));
395 407
396 if (m_item.CreatorID != ownerID) 408 if (m_item.CreatorID != ownerID)
397 { 409 {
398 if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) 410 if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
399 OSSLError( 411 return String.Format("{0} permission denied. Script permissions error.", function);
400 String.Format("{0} permission denied. Script permissions error.",
401 function));
402 412
403 } 413 }
404 } 414 }
405 } 415 }
416 return String.Empty;
406 } 417 }
407 418
408 internal void OSSLDeprecated(string function, string replacement) 419 internal void OSSLDeprecated(string function, string replacement)
@@ -1558,6 +1569,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 } 1569 }
1559 } 1570 }
1560 1571
1572 public string osGetPhysicsEngineType()
1573 {
1574 // High because it can be used to target attacks to known weaknesses
1575 // This would allow a new class of griefer scripts that don't even
1576 // require their user to know what they are doing (see script
1577 // kiddie)
1578 // Because it would be nice if scripts didn't blow up if the information
1579 // about the physics engine, this function returns an empty string if
1580 // the user does not have permission to see it. This as opposed to
1581 // throwing an exception.
1582 m_host.AddScriptLPS(1);
1583 string ret = String.Empty;
1584 if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType")))
1585 {
1586 if (m_ScriptEngine.World.PhysicsScene != null)
1587 {
1588 ret = m_ScriptEngine.World.PhysicsScene.EngineType;
1589 // An old physics engine might have an uninitialized engine type
1590 if (ret == null)
1591 ret = "unknown";
1592 }
1593 }
1594
1595 return ret;
1596 }
1597
1561 public string osGetSimulatorVersion() 1598 public string osGetSimulatorVersion()
1562 { 1599 {
1563 // High because it can be used to target attacks to known weaknesses 1600 // 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
259 259
260 string osGetScriptEngineName(); 260 string osGetScriptEngineName();
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 string osGetPhysicsEngineType();
262 Object osParseJSONNew(string JSON); 263 Object osParseJSONNew(string JSON);
263 Hashtable osParseJSON(string JSON); 264 Hashtable osParseJSON(string JSON);
264 265
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
420 return m_OSSL_Functions.osGetScriptEngineName(); 420 return m_OSSL_Functions.osGetScriptEngineName();
421 } 421 }
422 422
423 public string osGetPhysicsEngineType()
424 {
425 return m_OSSL_Functions.osGetPhysicsEngineType();
426 }
427
423 public string osGetSimulatorVersion() 428 public string osGetSimulatorVersion()
424 { 429 {
425 return m_OSSL_Functions.osGetSimulatorVersion(); 430 return m_OSSL_Functions.osGetSimulatorVersion();