diff options
Diffstat (limited to 'OpenSim')
29 files changed, 662 insertions, 335 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a8517e6..967fa44 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -6427,19 +6427,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6427 | #endregion | 6427 | #endregion |
6428 | 6428 | ||
6429 | AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; | 6429 | AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; |
6430 | if (handlerAgentRequestSit != null) | ||
6431 | if (!(agentRequestSit.AgentData == null | ||
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 | 6430 | ||
6440 | handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, | 6431 | if (handlerAgentRequestSit != null) |
6441 | agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); | 6432 | handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, |
6442 | } | 6433 | agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); |
6443 | } | 6434 | } |
6444 | return true; | 6435 | return true; |
6445 | } | 6436 | } |
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/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0219540..6979c33 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1954,6 +1954,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1954 | { | 1954 | { |
1955 | if (ParentID != 0) | 1955 | if (ParentID != 0) |
1956 | { | 1956 | { |
1957 | var targetPart = m_scene.GetSceneObjectPart(targetID); | ||
1958 | if (targetPart != null && targetPart.LocalId == ParentID) | ||
1959 | return; // already sitting here, ignore | ||
1960 | |||
1957 | StandUp(); | 1961 | StandUp(); |
1958 | } | 1962 | } |
1959 | 1963 | ||
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..ae54499 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | |||
@@ -166,7 +166,7 @@ public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet | |||
166 | 166 | ||
167 | // If Debug logging level, enable logging from the unmanaged code | 167 | // If Debug logging level, enable logging from the unmanaged code |
168 | m_DebugLogCallbackHandle = null; | 168 | m_DebugLogCallbackHandle = null; |
169 | if (BSScene.m_log.IsDebugEnabled || PhysicsScene.PhysicsLogging.Enabled) | 169 | if (BSScene.m_log.IsDebugEnabled && PhysicsScene.PhysicsLogging.Enabled) |
170 | { | 170 | { |
171 | BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); | 171 | BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); |
172 | if (PhysicsScene.PhysicsLogging.Enabled) | 172 | if (PhysicsScene.PhysicsLogging.Enabled) |
@@ -202,7 +202,7 @@ private void BulletLoggerPhysLog(string msg) | |||
202 | } | 202 | } |
203 | 203 | ||
204 | public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, | 204 | public 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); |
@@ -212,6 +212,19 @@ public override void Shutdown(BulletWorld world) | |||
212 | { | 212 | { |
213 | BulletWorldUnman worldu = world as BulletWorldUnman; | 213 | BulletWorldUnman worldu = world as BulletWorldUnman; |
214 | BSAPICPP.Shutdown2(worldu.ptr); | 214 | BSAPICPP.Shutdown2(worldu.ptr); |
215 | |||
216 | if (m_paramsHandle.IsAllocated) | ||
217 | { | ||
218 | m_paramsHandle.Free(); | ||
219 | } | ||
220 | if (m_collisionArrayPinnedHandle.IsAllocated) | ||
221 | { | ||
222 | m_collisionArrayPinnedHandle.Free(); | ||
223 | } | ||
224 | if (m_updateArrayPinnedHandle.IsAllocated) | ||
225 | { | ||
226 | m_updateArrayPinnedHandle.Free(); | ||
227 | } | ||
215 | } | 228 | } |
216 | 229 | ||
217 | public override bool PushUpdate(BulletBody obj) | 230 | public override bool PushUpdate(BulletBody obj) |
@@ -327,6 +340,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet | |||
327 | BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); | 340 | BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); |
328 | } | 341 | } |
329 | 342 | ||
343 | public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) | ||
344 | { | ||
345 | BulletShapeUnman shapeu = pShape as BulletShapeUnman; | ||
346 | BSAPICPP.UpdateChildTransform2(shapeu.ptr, childIndex, pos, rot, shouldRecalculateLocalAabb); | ||
347 | } | ||
348 | |||
330 | public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) | 349 | public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) |
331 | { | 350 | { |
332 | BulletShapeUnman shapeu = shape as BulletShapeUnman; | 351 | BulletShapeUnman shapeu = shape as BulletShapeUnman; |
@@ -1357,6 +1376,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap | |||
1357 | public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); | 1376 | public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); |
1358 | 1377 | ||
1359 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1378 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
1379 | public static extern void UpdateChildTransform2(IntPtr pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); | ||
1380 | |||
1381 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1360 | public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); | 1382 | public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); |
1361 | 1383 | ||
1362 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1384 | [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 | ||
343 | public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); | 343 | public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); |
344 | 344 | ||
345 | public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); | ||
346 | |||
345 | public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); | 347 | public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); |
346 | 348 | ||
347 | public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); | 349 | public 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..e434412 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; | ||
128 | private bool enableAngularDeflection; | ||
129 | private bool enableAngularBanking; | ||
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 = false; | ||
145 | enableAngularBanking = false; | ||
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,20 +645,24 @@ 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; |
652 | private Vector3 m_knownRotationalImpulse; | ||
625 | private Vector3 m_knownForwardVelocity; // vehicle relative forward speed | 653 | private Vector3 m_knownForwardVelocity; // vehicle relative forward speed |
626 | 654 | ||
627 | private const int m_knownChangedPosition = 1 << 0; | 655 | private const int m_knownChangedPosition = 1 << 0; |
628 | private const int m_knownChangedVelocity = 1 << 1; | 656 | private const int m_knownChangedVelocity = 1 << 1; |
629 | private const int m_knownChangedForce = 1 << 2; | 657 | private const int m_knownChangedForce = 1 << 2; |
630 | private const int m_knownChangedOrientation = 1 << 3; | 658 | private const int m_knownChangedForceImpulse = 1 << 3; |
631 | private const int m_knownChangedRotationalVelocity = 1 << 4; | 659 | private const int m_knownChangedOrientation = 1 << 4; |
632 | private const int m_knownChangedRotationalForce = 1 << 5; | 660 | private const int m_knownChangedRotationalVelocity = 1 << 5; |
633 | private const int m_knownChangedTerrainHeight = 1 << 6; | 661 | private const int m_knownChangedRotationalForce = 1 << 6; |
634 | private const int m_knownChangedWaterLevel = 1 << 7; | 662 | private const int m_knownChangedRotationalImpulse = 1 << 7; |
635 | private const int m_knownChangedForwardVelocity = 1 << 8; | 663 | private const int m_knownChangedTerrainHeight = 1 << 8; |
664 | private const int m_knownChangedWaterLevel = 1 << 9; | ||
665 | private const int m_knownChangedForwardVelocity = 1 <<10; | ||
636 | 666 | ||
637 | private void ForgetKnownVehicleProperties() | 667 | private void ForgetKnownVehicleProperties() |
638 | { | 668 | { |
@@ -653,21 +683,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
653 | if ((m_knownChanged & m_knownChangedVelocity) != 0) | 683 | if ((m_knownChanged & m_knownChangedVelocity) != 0) |
654 | { | 684 | { |
655 | Prim.ForceVelocity = m_knownVelocity; | 685 | Prim.ForceVelocity = m_knownVelocity; |
656 | PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); | 686 | // Fake out Bullet by making it think the velocity is the same as last time. |
687 | // Bullet does a bunch of smoothing for changing parameters. | ||
688 | // Since the vehicle is demanding this setting, we override Bullet's smoothing | ||
689 | // by telling Bullet the value was the same last time. | ||
690 | PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); | ||
657 | } | 691 | } |
658 | 692 | ||
659 | if ((m_knownChanged & m_knownChangedForce) != 0) | 693 | if ((m_knownChanged & m_knownChangedForce) != 0) |
660 | Prim.AddForce((Vector3)m_knownForce, false, true); | 694 | Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); |
695 | |||
696 | if ((m_knownChanged & m_knownChangedForceImpulse) != 0) | ||
697 | Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); | ||
661 | 698 | ||
662 | if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) | 699 | if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) |
663 | { | 700 | { |
664 | Prim.ForceRotationalVelocity = m_knownRotationalVelocity; | 701 | 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); | 702 | PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); |
667 | } | 703 | } |
668 | 704 | ||
705 | if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0) | ||
706 | Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/); | ||
707 | |||
669 | if ((m_knownChanged & m_knownChangedRotationalForce) != 0) | 708 | if ((m_knownChanged & m_knownChangedRotationalForce) != 0) |
670 | Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); | 709 | { |
710 | Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); | ||
711 | } | ||
671 | 712 | ||
672 | // If we set one of the values (ie, the physics engine didn't do it) we must force | 713 | // 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. | 714 | // an UpdateProperties event to send the changes up to the simulator. |
@@ -757,15 +798,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
757 | } | 798 | } |
758 | } | 799 | } |
759 | 800 | ||
760 | private void VehicleAddForce(Vector3 aForce) | 801 | private void VehicleAddForce(Vector3 pForce) |
761 | { | 802 | { |
762 | if ((m_knownHas & m_knownChangedForce) == 0) | 803 | if ((m_knownHas & m_knownChangedForce) == 0) |
763 | { | 804 | { |
764 | m_knownForce = Vector3.Zero; | 805 | m_knownForce = Vector3.Zero; |
806 | m_knownHas |= m_knownChangedForce; | ||
765 | } | 807 | } |
766 | m_knownForce += aForce; | 808 | m_knownForce += pForce; |
767 | m_knownChanged |= m_knownChangedForce; | 809 | m_knownChanged |= m_knownChangedForce; |
768 | m_knownHas |= m_knownChangedForce; | 810 | } |
811 | |||
812 | private void VehicleAddForceImpulse(Vector3 pImpulse) | ||
813 | { | ||
814 | if ((m_knownHas & m_knownChangedForceImpulse) == 0) | ||
815 | { | ||
816 | m_knownForceImpulse = Vector3.Zero; | ||
817 | m_knownHas |= m_knownChangedForceImpulse; | ||
818 | } | ||
819 | m_knownForceImpulse += pImpulse; | ||
820 | m_knownChanged |= m_knownChangedForceImpulse; | ||
769 | } | 821 | } |
770 | 822 | ||
771 | private Vector3 VehicleRotationalVelocity | 823 | private Vector3 VehicleRotationalVelocity |
@@ -796,6 +848,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
796 | m_knownChanged |= m_knownChangedRotationalForce; | 848 | m_knownChanged |= m_knownChangedRotationalForce; |
797 | m_knownHas |= m_knownChangedRotationalForce; | 849 | m_knownHas |= m_knownChangedRotationalForce; |
798 | } | 850 | } |
851 | private void VehicleAddRotationalImpulse(Vector3 pImpulse) | ||
852 | { | ||
853 | if ((m_knownHas & m_knownChangedRotationalImpulse) == 0) | ||
854 | { | ||
855 | m_knownRotationalImpulse = Vector3.Zero; | ||
856 | m_knownHas |= m_knownChangedRotationalImpulse; | ||
857 | } | ||
858 | m_knownRotationalImpulse += pImpulse; | ||
859 | m_knownChanged |= m_knownChangedRotationalImpulse; | ||
860 | } | ||
861 | |||
799 | // Vehicle relative forward velocity | 862 | // Vehicle relative forward velocity |
800 | private Vector3 VehicleForwardVelocity | 863 | private Vector3 VehicleForwardVelocity |
801 | { | 864 | { |
@@ -844,86 +907,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
844 | if (PhysicsScene.VehiclePhysicalLoggingEnabled) | 907 | if (PhysicsScene.VehiclePhysicalLoggingEnabled) |
845 | PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); | 908 | PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); |
846 | 909 | ||
847 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", | 910 | VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", |
848 | Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); | 911 | Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); |
849 | } | 912 | } |
850 | 913 | ||
851 | // Apply the effect of the linear motor and other linear motions (like hover and float). | 914 | // Apply the effect of the linear motor and other linear motions (like hover and float). |
852 | private void MoveLinear(float pTimestep) | 915 | private void MoveLinear(float pTimestep) |
853 | { | 916 | { |
854 | Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); | 917 | ComputeLinearVelocity(pTimestep); |
855 | |||
856 | // The movement computed in the linear motor is relative to the vehicle | ||
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 | 918 | ||
867 | Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); | 919 | ComputeLinearTerrainHeightCorrection(pTimestep); |
868 | 920 | ||
869 | Vector3 hoverContribution = ComputeLinearHover(pTimestep); | 921 | ComputeLinearHover(pTimestep); |
870 | 922 | ||
871 | ComputeLinearBlockingEndPoint(pTimestep); | 923 | ComputeLinearBlockingEndPoint(pTimestep); |
872 | 924 | ||
873 | Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); | 925 | ComputeLinearMotorUp(pTimestep); |
874 | |||
875 | // ================================================================== | ||
876 | Vector3 newVelocity = linearMotorContribution | ||
877 | + terrainHeightContribution | ||
878 | + hoverContribution | ||
879 | + limitMotorUpContribution; | ||
880 | 926 | ||
881 | Vector3 newForce = buoyancyContribution; | 927 | ApplyGravity(pTimestep); |
882 | 928 | ||
883 | // If not changing some axis, reduce out velocity | 929 | // If not changing some axis, reduce out velocity |
884 | if ((m_flags & (VehicleFlag.NO_X)) != 0) | 930 | if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) |
885 | newVelocity.X = 0; | 931 | { |
886 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) | 932 | Vector3 vel = VehicleVelocity; |
887 | newVelocity.Y = 0; | 933 | if ((m_flags & (VehicleFlag.NO_X)) != 0) |
888 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | 934 | vel.X = 0; |
889 | newVelocity.Z = 0; | 935 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) |
936 | vel.Y = 0; | ||
937 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | ||
938 | vel.Z = 0; | ||
939 | VehicleVelocity = vel; | ||
940 | } | ||
890 | 941 | ||
891 | // ================================================================== | 942 | // ================================================================== |
892 | // Clamp high or low velocities | 943 | // Clamp high or low velocities |
893 | float newVelocityLengthSq = newVelocity.LengthSquared(); | 944 | float newVelocityLengthSq = VehicleVelocity.LengthSquared(); |
894 | if (newVelocityLengthSq > 1000f) | 945 | if (newVelocityLengthSq > 1000f) |
895 | { | 946 | { |
896 | newVelocity /= newVelocity.Length(); | 947 | VehicleVelocity /= VehicleVelocity.Length(); |
897 | newVelocity *= 1000f; | 948 | VehicleVelocity *= 1000f; |
898 | } | 949 | } |
899 | else if (newVelocityLengthSq < 0.001f) | 950 | else if (newVelocityLengthSq < 0.001f) |
900 | newVelocity = Vector3.Zero; | 951 | VehicleVelocity = Vector3.Zero; |
901 | 952 | ||
902 | // ================================================================== | 953 | VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity ); |
903 | // Stuff new linear velocity into the vehicle. | 954 | |
904 | // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. | 955 | } // end MoveLinear() |
905 | VehicleVelocity = newVelocity; | ||
906 | 956 | ||
907 | // Other linear forces are applied as forces. | 957 | public void ComputeLinearVelocity(float pTimestep) |
908 | Vector3 totalDownForce = newForce * m_vehicleMass; | 958 | { |
909 | if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) | 959 | Vector3 linearMotorStep = m_linearMotor.Step(pTimestep); |
960 | |||
961 | // The movement computed in the linear motor is relative to the vehicle | ||
962 | // coordinates. Rotate the movement to world coordinates. | ||
963 | Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation; | ||
964 | |||
965 | // If we're a ground vehicle, don't loose any Z action (like gravity acceleration). | ||
966 | float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z | ||
967 | if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) | ||
968 | { | ||
969 | if (!Prim.IsColliding) | ||
970 | { | ||
971 | // If a ground vehicle and not on the ground, I want gravity effect | ||
972 | mixFactor = 0.2f; | ||
973 | } | ||
974 | } | ||
975 | else | ||
910 | { | 976 | { |
911 | VehicleAddForce(totalDownForce); | 977 | // I'm not a ground vehicle but don't totally loose the effect of the environment |
978 | mixFactor = 0.8f; | ||
912 | } | 979 | } |
980 | linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z; | ||
913 | 981 | ||
914 | VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", | 982 | // What we want to contribute to the vehicle's existing velocity |
915 | Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); | 983 | 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 | 984 | ||
922 | } // end MoveLinear() | 985 | // Act against the inertia of the vehicle |
986 | linearMotorForce *= m_vehicleMass; | ||
923 | 987 | ||
924 | public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) | 988 | VehicleAddForceImpulse(linearMotorForce * pTimestep); |
989 | |||
990 | VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", | ||
991 | Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); | ||
992 | } | ||
993 | |||
994 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) | ||
925 | { | 995 | { |
926 | Vector3 ret = Vector3.Zero; | ||
927 | // If below the terrain, move us above the ground a little. | 996 | // 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. | 997 | // TODO: Consider taking the rotated size of the object or possibly casting a ray. |
929 | if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) | 998 | if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) |
@@ -935,13 +1004,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
935 | VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", | 1004 | VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", |
936 | Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); | 1005 | Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); |
937 | } | 1006 | } |
938 | return ret; | ||
939 | } | 1007 | } |
940 | 1008 | ||
941 | public Vector3 ComputeLinearHover(float pTimestep) | 1009 | public void ComputeLinearHover(float pTimestep) |
942 | { | 1010 | { |
943 | Vector3 ret = Vector3.Zero; | ||
944 | |||
945 | // m_VhoverEfficiency: 0=bouncy, 1=totally damped | 1011 | // m_VhoverEfficiency: 0=bouncy, 1=totally damped |
946 | // m_VhoverTimescale: time to achieve height | 1012 | // m_VhoverTimescale: time to achieve height |
947 | if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) | 1013 | if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) |
@@ -974,23 +1040,42 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
974 | Vector3 pos = VehiclePosition; | 1040 | Vector3 pos = VehiclePosition; |
975 | pos.Z = m_VhoverTargetHeight; | 1041 | pos.Z = m_VhoverTargetHeight; |
976 | VehiclePosition = pos; | 1042 | VehiclePosition = pos; |
1043 | |||
1044 | VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos); | ||
977 | } | 1045 | } |
978 | } | 1046 | } |
979 | else | 1047 | else |
980 | { | 1048 | { |
981 | // Error is positive if below the target and negative if above. | 1049 | // Error is positive if below the target and negative if above. |
982 | float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; | 1050 | Vector3 hpos = VehiclePosition; |
1051 | float verticalError = m_VhoverTargetHeight - hpos.Z; | ||
1052 | float verticalCorrection = verticalError / m_VhoverTimescale; | ||
1053 | verticalCorrection *= m_VhoverEfficiency; | ||
1054 | |||
1055 | hpos.Z += verticalCorrection; | ||
1056 | VehiclePosition = hpos; | ||
1057 | |||
1058 | // Since we are hovering, we need to do the opposite of falling -- get rid of world Z | ||
1059 | Vector3 vel = VehicleVelocity; | ||
1060 | vel.Z = 0f; | ||
1061 | VehicleVelocity = vel; | ||
1062 | |||
1063 | /* | ||
983 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; | 1064 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; |
1065 | Vector3 verticalCorrection = new Vector3(0f, 0f, verticalCorrectionVelocity); | ||
1066 | verticalCorrection *= m_vehicleMass; | ||
984 | 1067 | ||
985 | // TODO: implement m_VhoverEfficiency correctly | 1068 | // TODO: implement m_VhoverEfficiency correctly |
986 | ret = new Vector3(0f, 0f, verticalCorrectionVelocity); | 1069 | VehicleAddForceImpulse(verticalCorrection); |
1070 | */ | ||
1071 | |||
1072 | VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}", | ||
1073 | Prim.LocalID, VehiclePosition, m_VhoverEfficiency, | ||
1074 | m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, | ||
1075 | verticalError, verticalCorrection); | ||
987 | } | 1076 | } |
988 | 1077 | ||
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 | } | 1078 | } |
992 | |||
993 | return ret; | ||
994 | } | 1079 | } |
995 | 1080 | ||
996 | public bool ComputeLinearBlockingEndPoint(float pTimestep) | 1081 | public bool ComputeLinearBlockingEndPoint(float pTimestep) |
@@ -1045,30 +1130,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1045 | // TODO: this code is wrong. Also, what should it do for boats (height from water)? | 1130 | // 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 | 1131 | // This is just using the ground and a general collision check. Should really be using |
1047 | // a downward raycast to find what is below. | 1132 | // a downward raycast to find what is below. |
1048 | public Vector3 ComputeLinearMotorUp(float pTimestep) | 1133 | public void ComputeLinearMotorUp(float pTimestep) |
1049 | { | 1134 | { |
1050 | Vector3 ret = Vector3.Zero; | 1135 | Vector3 ret = Vector3.Zero; |
1051 | float distanceAboveGround = 0f; | ||
1052 | 1136 | ||
1053 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) | 1137 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) |
1054 | { | 1138 | { |
1139 | // This code tries to decide if the object is not on the ground and then pushing down | ||
1140 | /* | ||
1055 | float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); | 1141 | float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); |
1056 | distanceAboveGround = VehiclePosition.Z - targetHeight; | 1142 | distanceAboveGround = VehiclePosition.Z - targetHeight; |
1057 | // Not colliding if the vehicle is off the ground | 1143 | // Not colliding if the vehicle is off the ground |
1058 | if (!Prim.IsColliding) | 1144 | if (!Prim.IsColliding) |
1059 | { | 1145 | { |
1060 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); | 1146 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); |
1061 | ret = new Vector3(0, 0, -distanceAboveGround); | 1147 | VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); |
1062 | } | 1148 | } |
1063 | // TODO: this calculation is wrong. From the description at | 1149 | // TODO: this calculation is wrong. From the description at |
1064 | // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce | 1150 | // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce |
1065 | // has a decay factor. This says this force should | 1151 | // has a decay factor. This says this force should |
1066 | // be computed with a motor. | 1152 | // be computed with a motor. |
1067 | // TODO: add interaction with banking. | 1153 | // TODO: add interaction with banking. |
1068 | } | 1154 | 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); | 1155 | Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); |
1071 | return ret; | 1156 | */ |
1157 | |||
1158 | // Another approach is to measure if we're going up. If going up and not colliding, | ||
1159 | // the vehicle is in the air. Fix that by pushing down. | ||
1160 | if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) | ||
1161 | { | ||
1162 | // Get rid of any of the velocity vector that is pushing us up. | ||
1163 | VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z); | ||
1164 | |||
1165 | // If we're pointed up into the air, we should nose down | ||
1166 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; | ||
1167 | // The rotation around the Y axis is pitch up or down | ||
1168 | if (pointingDirection.Y > 0.01f) | ||
1169 | { | ||
1170 | float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y); | ||
1171 | Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f); | ||
1172 | // Rotate into world coordinates and apply to vehicle | ||
1173 | angularCorrectionVector *= VehicleOrientation; | ||
1174 | VehicleAddAngularForce(angularCorrectionVector); | ||
1175 | VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}", | ||
1176 | Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector); | ||
1177 | } | ||
1178 | else | ||
1179 | { | ||
1180 | VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}", | ||
1181 | Prim.LocalID, VehicleVelocity, pointingDirection); | ||
1182 | } | ||
1183 | } | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1187 | private void ApplyGravity(float pTimeStep) | ||
1188 | { | ||
1189 | Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; | ||
1190 | VehicleAddForce(appliedGravity); | ||
1191 | |||
1192 | VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", | ||
1193 | Prim.LocalID, m_VehicleGravity, appliedGravity); | ||
1072 | } | 1194 | } |
1073 | 1195 | ||
1074 | // ======================================================================= | 1196 | // ======================================================================= |
@@ -1088,6 +1210,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1088 | // for preventing ground vehicles with large linear deflection, like bumper cars, | 1210 | // for preventing ground vehicles with large linear deflection, like bumper cars, |
1089 | // from climbing their linear deflection into the sky. | 1211 | // 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 | 1212 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement |
1213 | // TODO: This is here because this is where ODE put it but documentation says it | ||
1214 | // is a linear effect. Where should this check go? | ||
1091 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | 1215 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) |
1092 | { | 1216 | { |
1093 | angularMotorContribution.X = 0f; | 1217 | angularMotorContribution.X = 0f; |
@@ -1179,7 +1303,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1179 | Vector3 ret = Vector3.Zero; | 1303 | Vector3 ret = Vector3.Zero; |
1180 | 1304 | ||
1181 | // If vertical attaction timescale is reasonable | 1305 | // If vertical attaction timescale is reasonable |
1182 | if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1306 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1183 | { | 1307 | { |
1184 | // Take a vector pointing up and convert it from world to vehicle relative coords. | 1308 | // Take a vector pointing up and convert it from world to vehicle relative coords. |
1185 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; | 1309 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; |
@@ -1230,7 +1354,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1230 | // this creates an over-correction and then wabbling as the target is overshot. | 1354 | // this creates an over-correction and then wabbling as the target is overshot. |
1231 | // TODO: rethink how the different correction computations inter-relate. | 1355 | // TODO: rethink how the different correction computations inter-relate. |
1232 | 1356 | ||
1233 | if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) | 1357 | if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) |
1234 | { | 1358 | { |
1235 | // The direction the vehicle is moving | 1359 | // The direction the vehicle is moving |
1236 | Vector3 movingDirection = VehicleVelocity; | 1360 | Vector3 movingDirection = VehicleVelocity; |
@@ -1303,7 +1427,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1303 | { | 1427 | { |
1304 | Vector3 ret = Vector3.Zero; | 1428 | Vector3 ret = Vector3.Zero; |
1305 | 1429 | ||
1306 | if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1430 | if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1307 | { | 1431 | { |
1308 | // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. | 1432 | // 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 | 1433 | // 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..2dc89b5 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. |
41 | sealed class BSLinksetCompoundInfo : BSLinksetInfo | 41 | sealed 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,8 +194,12 @@ public sealed class BSLinksetCompound : BSLinkset | |||
182 | && !physicalUpdate | 194 | && !physicalUpdate |
183 | && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) | 195 | && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) |
184 | { | 196 | { |
185 | updated.LinksetInfo = null; | 197 | // TODO: replace this with are calculation of the child prim's orientation and pos. |
186 | ScheduleRebuild(updated); | 198 | // TODO: for the moment, don't rebuild the compound shape. |
199 | // This is often just the car turning its wheels. When we can just reorient the one | ||
200 | // member shape of the compound shape, the overhead of rebuilding won't be a problem. | ||
201 | // updated.LinksetInfo = null; | ||
202 | // ScheduleRebuild(updated); | ||
187 | } | 203 | } |
188 | } | 204 | } |
189 | 205 | ||
@@ -230,7 +246,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
230 | if (inTaintTime) | 246 | if (inTaintTime) |
231 | { | 247 | { |
232 | OMV.Vector3 oldPos = child.RawPosition; | 248 | OMV.Vector3 oldPos = child.RawPosition; |
233 | child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; | 249 | child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot; |
234 | child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; | 250 | child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; |
235 | DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", | 251 | DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", |
236 | child.LocalID, oldPos, lci, child.RawPosition); | 252 | child.LocalID, oldPos, lci, child.RawPosition); |
@@ -238,7 +254,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
238 | else | 254 | else |
239 | { | 255 | { |
240 | // TaintedObject is not used here so the raw position is set now and not at taint-time. | 256 | // TaintedObject is not used here so the raw position is set now and not at taint-time. |
241 | child.Position = LinksetRoot.RawPosition + lci.OffsetPos; | 257 | child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot; |
242 | child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; | 258 | child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; |
243 | } | 259 | } |
244 | } | 260 | } |
@@ -306,6 +322,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
306 | // Constraint linksets are rebuilt every time. | 322 | // Constraint linksets are rebuilt every time. |
307 | // Note that this works for rebuilding just the root after a linkset is taken apart. | 323 | // Note that this works for rebuilding just the root after a linkset is taken apart. |
308 | // Called at taint time!! | 324 | // Called at taint time!! |
325 | private bool disableCOM = true; // disable until we get this debugged | ||
309 | private void RecomputeLinksetCompound() | 326 | private void RecomputeLinksetCompound() |
310 | { | 327 | { |
311 | try | 328 | try |
@@ -316,10 +333,34 @@ public sealed class BSLinksetCompound : BSLinkset | |||
316 | // Cause the root shape to be rebuilt as a compound object with just the root in it | 333 | // Cause the root shape to be rebuilt as a compound object with just the root in it |
317 | LinksetRoot.ForceBodyShapeRebuild(true); | 334 | LinksetRoot.ForceBodyShapeRebuild(true); |
318 | 335 | ||
336 | // The center of mass for the linkset is the geometric center of the group. | ||
337 | // Compute a displacement for each component so it is relative to the center-of-mass. | ||
338 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass | ||
339 | OMV.Vector3 centerOfMass; | ||
340 | OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; | ||
341 | if (disableCOM) // DEBUG DEBUG | ||
342 | { // DEBUG DEBUG | ||
343 | centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG | ||
344 | LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; | ||
345 | } // DEBUG DEBUG | ||
346 | else | ||
347 | { | ||
348 | centerOfMass = ComputeLinksetGeometricCenter(); | ||
349 | centerDisplacement = centerOfMass - LinksetRoot.RawPosition; | ||
350 | |||
351 | // Since we're displacing the center of the shape, we need to move the body in the world | ||
352 | LinksetRoot.PositionDisplacement = centerDisplacement; | ||
353 | |||
354 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); | ||
355 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", | ||
356 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); | ||
357 | } | ||
358 | |||
319 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", | 359 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", |
320 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); | 360 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); |
321 | 361 | ||
322 | // Add a shape for each of the other children in the linkset | 362 | // Add a shape for each of the other children in the linkset |
363 | int memberIndex = 1; | ||
323 | ForEachMember(delegate(BSPhysObject cPrim) | 364 | ForEachMember(delegate(BSPhysObject cPrim) |
324 | { | 365 | { |
325 | if (!IsRoot(cPrim)) | 366 | if (!IsRoot(cPrim)) |
@@ -331,19 +372,21 @@ public sealed class BSLinksetCompound : BSLinkset | |||
331 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | 372 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; |
332 | if (lci == null) | 373 | if (lci == null) |
333 | { | 374 | { |
334 | // Each child position and rotation is given relative to the root. | 375 | // Each child position and rotation is given relative to the center-of-mass. |
335 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | 376 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); |
336 | OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; | 377 | OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; |
378 | OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; | ||
337 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | 379 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; |
338 | 380 | ||
339 | // Save relative position for recomputing child's world position after moving linkset. | 381 | // Save relative position for recomputing child's world position after moving linkset. |
340 | lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); | 382 | lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); |
383 | lci.OffsetFromRoot = displacementFromRoot; | ||
341 | cPrim.LinksetInfo = lci; | 384 | cPrim.LinksetInfo = lci; |
342 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | 385 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); |
343 | } | 386 | } |
344 | 387 | ||
345 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", | 388 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}", |
346 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); | 389 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci); |
347 | 390 | ||
348 | if (cPrim.PhysShape.isNativeShape) | 391 | if (cPrim.PhysShape.isNativeShape) |
349 | { | 392 | { |
@@ -359,7 +402,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
359 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); | 402 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); |
360 | BulletShape newShape = cPrim.PhysShape; | 403 | BulletShape newShape = cPrim.PhysShape; |
361 | cPrim.PhysShape = saveShape; | 404 | cPrim.PhysShape = saveShape; |
362 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); | 405 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); |
363 | } | 406 | } |
364 | else | 407 | else |
365 | { | 408 | { |
@@ -371,8 +414,10 @@ public sealed class BSLinksetCompound : BSLinkset | |||
371 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", | 414 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", |
372 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); | 415 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); |
373 | } | 416 | } |
374 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); | 417 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); |
375 | } | 418 | } |
419 | lci.Index = memberIndex; | ||
420 | memberIndex++; | ||
376 | } | 421 | } |
377 | return false; // 'false' says to move onto the next child in the list | 422 | return false; // 'false' says to move onto the next child in the list |
378 | }); | 423 | }); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 23d573f..862dbf6 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; } |
@@ -317,13 +318,13 @@ public static class BSParam | |||
317 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, | 318 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, |
318 | (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), | 319 | (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), |
319 | new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , | 320 | new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , |
320 | 0f, // set to zero to disable | 321 | 0.3f, // set to zero to disable |
321 | (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, | 322 | (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, |
322 | (s) => { return CcdMotionThreshold; }, | 323 | (s) => { return CcdMotionThreshold; }, |
323 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, | 324 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, |
324 | (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ), | 325 | (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ), |
325 | new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , | 326 | new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , |
326 | 0f, | 327 | 0.2f, |
327 | (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, | 328 | (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, |
328 | (s) => { return CcdSweptSphereRadius; }, | 329 | (s) => { return CcdSweptSphereRadius; }, |
329 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, | 330 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, |
@@ -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, |
@@ -459,7 +465,7 @@ public static class BSParam | |||
459 | (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, | 465 | (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, |
460 | (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), | 466 | (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), |
461 | new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", | 467 | new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", |
462 | ConfigurationParameters.numericFalse, | 468 | ConfigurationParameters.numericTrue, |
463 | (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, | 469 | (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, |
464 | (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, | 470 | (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, |
465 | (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), | 471 | (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), |
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 8fd054f..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; |
@@ -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 @@ | |||
1 | CURRENT PRIORITIES | 1 | CURRENT PRIORITIES |
2 | ================================================= | 2 | ================================================= |
3 | Nebadon vehicles turning funny in arena | ||
4 | limitMotorUp calibration (more down?) | ||
5 | Vehicle angular vertical attraction | ||
6 | Vehicle angular deflection | ||
7 | Preferred orientation angular correction fix | ||
8 | vehicle angular banking | ||
3 | Avatars walking up stairs (HALF DONE) | 9 | Avatars walking up stairs (HALF DONE) |
10 | Radius of the capsule affects ability to climb edges. | ||
4 | Vehicle movement on terrain smoothness | 11 | Vehicle movement on terrain smoothness |
5 | limitMotorUp calibration (more down?) | ||
6 | Preferred orientation angular correction fix | ||
7 | Surfboard go wonky when turning | 12 | Surfboard 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? |
9 | Boats float low in the water | 14 | Boats float low in the water (DONE) |
10 | Avatar movement | 15 | Avatar 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 | ||
34 | VEHICLES TODO LIST: | 39 | VEHICLES TODO LIST: |
35 | ================================================= | 40 | ================================================= |
36 | Angular motor direction is global coordinates rather than local coordinates | ||
37 | Border crossing with linked vehicle causes crash | 41 | Border crossing with linked vehicle causes crash |
38 | Vehicles (Move smoothly) | 42 | Vehicles (Move smoothly) |
39 | Add vehicle collisions so IsColliding is properly reported. | ||
40 | Needed for banking, limitMotorUp, movementLimiting, ... | ||
41 | VehicleAddForce is not scaled by the simulation step but it is only | ||
42 | applied for one step. Should it be scaled? | ||
43 | Some vehicles should not be able to turn if no speed or off ground. | 43 | Some vehicles should not be able to turn if no speed or off ground. |
44 | Cannot edit/move a vehicle being ridden: it jumps back to the origional position. | 44 | Cannot edit/move a vehicle being ridden: it jumps back to the origional position. |
45 | Neb car jiggling left and right | 45 | Neb 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. |
48 | Implement referenceFrame for all the motion routines. | 48 | Implement referenceFrame for all the motion routines. |
49 | For limitMotorUp, use raycast down to find if vehicle is in the air. | ||
49 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. | 50 | Angular 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. |
51 | Verify llGetVel() is returning a smooth and good value for vehicle movement. | 52 | Verify llGetVel() is returning a smooth and good value for vehicle movement. |
@@ -54,14 +55,13 @@ Implement function efficiency for lineaar and angular motion. | |||
54 | After getting off a vehicle, the root prim is phantom (can be walked through) | 55 | After 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 |
56 | Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) | 57 | Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) |
57 | For limitMotorUp, use raycast down to find if vehicle is in the air. | ||
58 | Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). | 58 | Remove 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. |
60 | Incorporate inter-relationship of angular corrections. For instance, angularDeflection | 60 | Incorporate 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 | ||
64 | BULLETSIM TODO LIST: | 64 | GENERAL TODO LIST: |
65 | ================================================= | 65 | ================================================= |
66 | Implement an avatar mesh shape. The Bullet capsule is way too limited. | 66 | Implement 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 | |||
121 | Verify/think through scripts in children of linksets. What do they reference | 121 | Verify/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, ... |
123 | Confirm constraint linksets still work after making all the changes for compound linksets. | 123 | Confirm constraint linksets still work after making all the changes for compound linksets. |
124 | Use PostTaint callback to do rebuilds for constraint linksets to reduce rebuilding | ||
124 | Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. | 125 | Add '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. |
126 | Disable 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, ... | ||
129 | Speed up creation of large physical linksets | 127 | Speed 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 | |||
138 | Use the HACD convex hull routine in Bullet rather than the C# version. | 136 | Use the HACD convex hull routine in Bullet rather than the C# version. |
139 | Do we need to do convex hulls all the time? Can complex meshes be left meshes? | 137 | Do 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 |
141 | Test 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. | ||
143 | Debounce avatar contact so legs don't keep folding up when standing. | 140 | Debounce avatar contact so legs don't keep folding up when standing. |
144 | Implement LSL physics controls. Like STATUS_ROTATE_X. | 141 | Implement LSL physics controls. Like STATUS_ROTATE_X. |
145 | Add border extensions to terrain to help region crossings and objects leaving region. | 142 | Add border extensions to terrain to help region crossings and objects leaving region. |
146 | Use a different capsule shape for avatar when sitting | 143 | Use 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 | |||
150 | Performance test with lots of avatars. Can BulletSim support a thousand? | 146 | Performance test with lots of avatars. Can BulletSim support a thousand? |
151 | Optimize collisions in C++: only send up to the object subscribed to collisions. | 147 | Optimize 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) |
153 | Check whether SimMotionState needs large if statement (see TODO). | 149 | Check whether SimMotionState needs large if statement (see TODO). |
154 | |||
155 | Implement 'top colliders' info. | 150 | Implement 'top colliders' info. |
156 | Avatar jump | 151 | Avatar jump |
157 | Performance measurement and changes to make quicker. | 152 | Performance measurement and changes to make quicker. |
158 | Implement detailed physics stats (GetStats()). | 153 | Implement detailed physics stats (GetStats()). |
159 | |||
160 | Measure performance improvement from hulls | 154 | Measure performance improvement from hulls |
161 | Test not using ghost objects for volume detect implementation. | 155 | Test not using ghost objects for volume detect implementation. |
162 | Performance of closures and delegates for taint processing | 156 | Performance 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? |
165 | Is there are more efficient method of implementing pre and post step actions? | 159 | Is 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 | |||
168 | Physics Arena central pyramid: why is one side permiable? | 161 | Physics Arena central pyramid: why is one side permiable? |
169 | |||
170 | In SL, perfect spheres don't seem to have rolling friction. Add special case. | 162 | In SL, perfect spheres don't seem to have rolling friction. Add special case. |
171 | Enforce physical parameter min/max: | 163 | Enforce 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 | ||
179 | INTERNAL IMPROVEMENT/CLEANUP | 171 | INTERNAL IMPROVEMENT/CLEANUP |
180 | ================================================= | 172 | ================================================= |
173 | Can 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. | ||
181 | Create the physical wrapper classes (BulletBody, BulletShape) by methods on | 175 | Create 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. | |||
197 | Generalize Linkset and vehicles into PropertyManagers | 191 | Generalize 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. |
200 | Complete implemention of preStepActions | 194 | Better 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? | ||
203 | Implement linkset by setting position of children when root updated. (LinksetManual) | 196 | Implement linkset by setting position of children when root updated. (LinksetManual) |
204 | Linkset implementation using manual prim movement. | 197 | Linkset implementation using manual prim movement. |
205 | LinkablePrim class? Would that simplify/centralize the linkset logic? | 198 | LinkablePrim class? Would that simplify/centralize the linkset logic? |
206 | BSScene.UpdateParameterSet() is broken. How to set params on objects? | 199 | BSScene.UpdateParameterSet() is broken. How to set params on objects? |
207 | Remove HeightmapInfo from terrain specification | ||
208 | Since C++ code does not need terrain height, this structure et al are not needed. | ||
209 | Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will | 200 | Add 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() |
211 | Should taints check for existance or activeness of target? | 202 | Should 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? |
216 | Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) | 207 | Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) |
217 | Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? | 208 | Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? |
218 | There are TOO MANY interfaces from BulletSim core to Bullet itself | 209 | There 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) | |||
282 | Meshes rendering as bounding boxes (DONE) | 273 | Meshes 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) |
284 | llMoveToTarget (Resolution: added simple motor to update the position.) | 275 | llMoveToTarget (Resolution: added simple motor to update the position.) |
276 | Angular motor direction is global coordinates rather than local coordinates (DONE) | ||
277 | Add 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) | ||
280 | VehicleAddForce 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) | ||
283 | Complete implemention of preStepActions (DONE) | ||
284 | Replace vehicle step call with prestep event. | ||
285 | Is there a need for postStepActions? postStepTaints? | ||
286 | Disable 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, ... | ||
289 | Remove 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(); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 01a5e34..f172216 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -157,19 +157,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
157 | 157 | ||
158 | public UUID AppDomain { get; set; } | 158 | public UUID AppDomain { get; set; } |
159 | 159 | ||
160 | /// <summary> | ||
161 | /// Scene part in which this script instance is contained. | ||
162 | /// </summary> | ||
163 | public SceneObjectPart Part { get; private set; } | ||
164 | |||
160 | public string PrimName { get; private set; } | 165 | public string PrimName { get; private set; } |
161 | 166 | ||
162 | public string ScriptName { get; private set; } | 167 | public string ScriptName { get; private set; } |
163 | 168 | ||
164 | public UUID ItemID { get; private set; } | 169 | public UUID ItemID { get; private set; } |
165 | 170 | ||
166 | public UUID ObjectID { get; private set; } | 171 | public UUID ObjectID { get { return Part.UUID; } } |
167 | 172 | ||
168 | public uint LocalID { get; private set; } | 173 | public uint LocalID { get { return Part.LocalId; } } |
169 | 174 | ||
170 | public UUID RootObjectID { get; private set; } | 175 | public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } |
171 | 176 | ||
172 | public uint RootLocalID { get; private set; } | 177 | public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } |
173 | 178 | ||
174 | public UUID AssetID { get; private set; } | 179 | public UUID AssetID { get; private set; } |
175 | 180 | ||
@@ -214,10 +219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
214 | EventQueue = new Queue(32); | 219 | EventQueue = new Queue(32); |
215 | 220 | ||
216 | Engine = engine; | 221 | Engine = engine; |
217 | LocalID = part.LocalId; | 222 | Part = part; |
218 | ObjectID = part.UUID; | ||
219 | RootLocalID = part.ParentGroup.LocalId; | ||
220 | RootObjectID = part.ParentGroup.UUID; | ||
221 | ItemID = itemID; | 223 | ItemID = itemID; |
222 | AssetID = assetID; | 224 | AssetID = assetID; |
223 | PrimName = primName; | 225 | PrimName = primName; |
@@ -227,17 +229,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
227 | m_MaxScriptQueue = maxScriptQueue; | 229 | m_MaxScriptQueue = maxScriptQueue; |
228 | m_stateSource = stateSource; | 230 | m_stateSource = stateSource; |
229 | m_postOnRez = postOnRez; | 231 | m_postOnRez = postOnRez; |
230 | m_AttachedAvatar = part.ParentGroup.AttachedAvatar; | 232 | m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; |
231 | m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; | 233 | m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; |
232 | 234 | ||
233 | if (part != null) | 235 | lock (Part.TaskInventory) |
234 | { | 236 | { |
235 | lock (part.TaskInventory) | 237 | if (Part.TaskInventory.ContainsKey(ItemID)) |
236 | { | 238 | { |
237 | if (part.TaskInventory.ContainsKey(ItemID)) | 239 | ScriptTask = Part.TaskInventory[ItemID]; |
238 | { | ||
239 | ScriptTask = part.TaskInventory[ItemID]; | ||
240 | } | ||
241 | } | 240 | } |
242 | } | 241 | } |
243 | 242 | ||
@@ -322,7 +321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
322 | 321 | ||
323 | // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); | 322 | // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); |
324 | 323 | ||
325 | part.SetScriptEvents(ItemID, | 324 | Part.SetScriptEvents(ItemID, |
326 | (int)m_Script.GetStateEventFlags(State)); | 325 | (int)m_Script.GetStateEventFlags(State)); |
327 | 326 | ||
328 | if (!Running) | 327 | if (!Running) |
@@ -418,33 +417,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
418 | PostEvent(new EventParams("attach", | 417 | PostEvent(new EventParams("attach", |
419 | new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); | 418 | new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); |
420 | } | 419 | } |
421 | |||
422 | } | 420 | } |
423 | } | 421 | } |
424 | 422 | ||
425 | private void ReleaseControls() | 423 | private void ReleaseControls() |
426 | { | 424 | { |
427 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | 425 | int permsMask; |
428 | 426 | UUID permsGranter; | |
429 | if (part != null) | 427 | lock (Part.TaskInventory) |
430 | { | 428 | { |
431 | int permsMask; | 429 | if (!Part.TaskInventory.ContainsKey(ItemID)) |
432 | UUID permsGranter; | 430 | return; |
433 | lock (part.TaskInventory) | ||
434 | { | ||
435 | if (!part.TaskInventory.ContainsKey(ItemID)) | ||
436 | return; | ||
437 | 431 | ||
438 | permsGranter = part.TaskInventory[ItemID].PermsGranter; | 432 | permsGranter = Part.TaskInventory[ItemID].PermsGranter; |
439 | permsMask = part.TaskInventory[ItemID].PermsMask; | 433 | permsMask = Part.TaskInventory[ItemID].PermsMask; |
440 | } | 434 | } |
441 | 435 | ||
442 | if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) | 436 | if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) |
443 | { | 437 | { |
444 | ScenePresence presence = Engine.World.GetScenePresence(permsGranter); | 438 | ScenePresence presence = Engine.World.GetScenePresence(permsGranter); |
445 | if (presence != null) | 439 | if (presence != null) |
446 | presence.UnRegisterControlEventsToScript(LocalID, ItemID); | 440 | presence.UnRegisterControlEventsToScript(LocalID, ItemID); |
447 | } | ||
448 | } | 441 | } |
449 | } | 442 | } |
450 | 443 | ||
@@ -706,19 +699,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
706 | m_CollisionInQueue = false; | 699 | m_CollisionInQueue = false; |
707 | } | 700 | } |
708 | 701 | ||
709 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | ||
710 | |||
711 | if (DebugLevel >= 2) | 702 | if (DebugLevel >= 2) |
712 | m_log.DebugFormat( | 703 | m_log.DebugFormat( |
713 | "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", | 704 | "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", |
714 | data.EventName, | 705 | data.EventName, |
715 | ScriptName, | 706 | ScriptName, |
716 | part.Name, | 707 | Part.Name, |
717 | part.LocalId, | 708 | Part.LocalId, |
718 | part.ParentGroup.Name, | 709 | Part.ParentGroup.Name, |
719 | part.ParentGroup.UUID, | 710 | Part.ParentGroup.UUID, |
720 | part.AbsolutePosition, | 711 | Part.AbsolutePosition, |
721 | part.ParentGroup.Scene.Name); | 712 | Part.ParentGroup.Scene.Name); |
722 | 713 | ||
723 | m_DetectParams = data.DetectParams; | 714 | m_DetectParams = data.DetectParams; |
724 | 715 | ||
@@ -731,21 +722,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
731 | "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", | 722 | "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", |
732 | State, | 723 | State, |
733 | ScriptName, | 724 | ScriptName, |
734 | part.Name, | 725 | Part.Name, |
735 | part.LocalId, | 726 | Part.LocalId, |
736 | part.ParentGroup.Name, | 727 | Part.ParentGroup.Name, |
737 | part.ParentGroup.UUID, | 728 | Part.ParentGroup.UUID, |
738 | part.AbsolutePosition, | 729 | Part.AbsolutePosition, |
739 | part.ParentGroup.Scene.Name); | 730 | Part.ParentGroup.Scene.Name); |
740 | 731 | ||
741 | AsyncCommandManager.RemoveScript(Engine, | 732 | AsyncCommandManager.RemoveScript(Engine, |
742 | LocalID, ItemID); | 733 | LocalID, ItemID); |
743 | 734 | ||
744 | if (part != null) | 735 | Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); |
745 | { | ||
746 | part.SetScriptEvents(ItemID, | ||
747 | (int)m_Script.GetStateEventFlags(State)); | ||
748 | } | ||
749 | } | 736 | } |
750 | else | 737 | else |
751 | { | 738 | { |
@@ -804,17 +791,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
804 | text = text.Substring(0, 1000); | 791 | text = text.Substring(0, 1000); |
805 | Engine.World.SimChat(Utils.StringToBytes(text), | 792 | Engine.World.SimChat(Utils.StringToBytes(text), |
806 | ChatTypeEnum.DebugChannel, 2147483647, | 793 | ChatTypeEnum.DebugChannel, 2147483647, |
807 | part.AbsolutePosition, | 794 | Part.AbsolutePosition, |
808 | part.Name, part.UUID, false); | 795 | Part.Name, Part.UUID, false); |
809 | 796 | ||
810 | 797 | ||
811 | m_log.DebugFormat( | 798 | m_log.DebugFormat( |
812 | "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", | 799 | "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", |
813 | ScriptName, | 800 | ScriptName, |
814 | PrimName, | 801 | PrimName, |
815 | part.UUID, | 802 | Part.UUID, |
816 | part.AbsolutePosition, | 803 | Part.AbsolutePosition, |
817 | part.ParentGroup.Scene.Name, | 804 | Part.ParentGroup.Scene.Name, |
818 | text.Replace("\n", "\\n"), | 805 | text.Replace("\n", "\\n"), |
819 | e.InnerException); | 806 | e.InnerException); |
820 | } | 807 | } |
@@ -834,14 +821,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
834 | else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) | 821 | else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) |
835 | { | 822 | { |
836 | m_InSelfDelete = true; | 823 | m_InSelfDelete = true; |
837 | if (part != null) | 824 | Engine.World.DeleteSceneObject(Part.ParentGroup, false); |
838 | Engine.World.DeleteSceneObject(part.ParentGroup, false); | ||
839 | } | 825 | } |
840 | else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) | 826 | else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) |
841 | { | 827 | { |
842 | m_InSelfDelete = true; | 828 | m_InSelfDelete = true; |
843 | if (part != null) | 829 | Part.Inventory.RemoveInventoryItem(ItemID); |
844 | part.Inventory.RemoveInventoryItem(ItemID); | ||
845 | } | 830 | } |
846 | } | 831 | } |
847 | } | 832 | } |
@@ -888,15 +873,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
888 | ReleaseControls(); | 873 | ReleaseControls(); |
889 | 874 | ||
890 | Stop(timeout); | 875 | Stop(timeout); |
891 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | 876 | Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; |
892 | part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; | 877 | Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; |
893 | part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | ||
894 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); | 878 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); |
895 | EventQueue.Clear(); | 879 | EventQueue.Clear(); |
896 | m_Script.ResetVars(); | 880 | m_Script.ResetVars(); |
897 | State = "default"; | 881 | State = "default"; |
898 | 882 | ||
899 | part.SetScriptEvents(ItemID, | 883 | Part.SetScriptEvents(ItemID, |
900 | (int)m_Script.GetStateEventFlags(State)); | 884 | (int)m_Script.GetStateEventFlags(State)); |
901 | if (running) | 885 | if (running) |
902 | Start(); | 886 | Start(); |
@@ -913,16 +897,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
913 | ReleaseControls(); | 897 | ReleaseControls(); |
914 | 898 | ||
915 | m_Script.ResetVars(); | 899 | m_Script.ResetVars(); |
916 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | 900 | Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; |
917 | part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; | 901 | Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; |
918 | part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | ||
919 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); | 902 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); |
920 | 903 | ||
921 | EventQueue.Clear(); | 904 | EventQueue.Clear(); |
922 | m_Script.ResetVars(); | 905 | m_Script.ResetVars(); |
923 | State = "default"; | 906 | State = "default"; |
924 | 907 | ||
925 | part.SetScriptEvents(ItemID, | 908 | Part.SetScriptEvents(ItemID, |
926 | (int)m_Script.GetStateEventFlags(State)); | 909 | (int)m_Script.GetStateEventFlags(State)); |
927 | 910 | ||
928 | if (m_CurrentEvent != "state_entry") | 911 | if (m_CurrentEvent != "state_entry") |
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 3f208bf..2e6d279 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs | |||
@@ -280,8 +280,11 @@ namespace OpenSim.Server.Base | |||
280 | { | 280 | { |
281 | if (!(e is System.MissingMethodException)) | 281 | if (!(e is System.MissingMethodException)) |
282 | { | 282 | { |
283 | m_log.ErrorFormat("Error loading plugin {0} from {1}. Exception: {2}", | 283 | m_log.ErrorFormat("Error loading plugin {0} from {1}. Exception: {2}, {3}", |
284 | interfaceName, dllName, e.InnerException == null ? e.Message : e.InnerException.Message); | 284 | interfaceName, |
285 | dllName, | ||
286 | e.InnerException == null ? e.Message : e.InnerException.Message, | ||
287 | e.StackTrace); | ||
285 | } | 288 | } |
286 | return null; | 289 | return null; |
287 | } | 290 | } |