diff options
Diffstat (limited to 'OpenSim')
17 files changed, 561 insertions, 160 deletions
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index d703d78..9490013 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs | |||
@@ -110,10 +110,11 @@ namespace OpenSim.Framework.Console | |||
110 | // Remove initial help keyword | 110 | // Remove initial help keyword |
111 | helpParts.RemoveAt(0); | 111 | helpParts.RemoveAt(0); |
112 | 112 | ||
113 | help.Add(""); // Will become a newline. | ||
114 | |||
113 | // General help | 115 | // General help |
114 | if (helpParts.Count == 0) | 116 | if (helpParts.Count == 0) |
115 | { | 117 | { |
116 | help.Add(""); // Will become a newline. | ||
117 | help.Add(GeneralHelpText); | 118 | help.Add(GeneralHelpText); |
118 | help.AddRange(CollectAllCommandsHelp()); | 119 | help.AddRange(CollectAllCommandsHelp()); |
119 | } | 120 | } |
@@ -129,6 +130,8 @@ namespace OpenSim.Framework.Console | |||
129 | help.AddRange(CollectHelp(helpParts)); | 130 | help.AddRange(CollectHelp(helpParts)); |
130 | } | 131 | } |
131 | 132 | ||
133 | help.Add(""); // Will become a newline. | ||
134 | |||
132 | return help; | 135 | return help; |
133 | } | 136 | } |
134 | 137 | ||
@@ -199,14 +202,11 @@ namespace OpenSim.Framework.Console | |||
199 | 202 | ||
200 | string descriptiveHelp = commandInfo.descriptive_help; | 203 | string descriptiveHelp = commandInfo.descriptive_help; |
201 | 204 | ||
202 | // If we do have some descriptive help then insert a spacing line before and after for readability. | 205 | // If we do have some descriptive help then insert a spacing line before for readability. |
203 | if (descriptiveHelp != string.Empty) | 206 | if (descriptiveHelp != string.Empty) |
204 | help.Add(string.Empty); | 207 | help.Add(string.Empty); |
205 | 208 | ||
206 | help.Add(commandInfo.descriptive_help); | 209 | help.Add(commandInfo.descriptive_help); |
207 | |||
208 | if (descriptiveHelp != string.Empty) | ||
209 | help.Add(string.Empty); | ||
210 | } | 210 | } |
211 | else | 211 | else |
212 | { | 212 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index b06788b..83347e2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | |||
@@ -105,7 +105,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
105 | private static readonly string m_ResourceCostSelectedPath = "0103/"; | 105 | private static readonly string m_ResourceCostSelectedPath = "0103/"; |
106 | private static readonly string m_UpdateAgentInformationPath = "0500/"; | 106 | private static readonly string m_UpdateAgentInformationPath = "0500/"; |
107 | 107 | ||
108 | |||
109 | // These are callbacks which will be setup by the scene so that we can update scene data when we | 108 | // These are callbacks which will be setup by the scene so that we can update scene data when we |
110 | // receive capability calls | 109 | // receive capability calls |
111 | public NewInventoryItem AddNewInventoryItem = null; | 110 | public NewInventoryItem AddNewInventoryItem = null; |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 27cf204..cfc7e7e 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -322,6 +322,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
322 | 322 | ||
323 | if (asset != null) | 323 | if (asset != null) |
324 | { | 324 | { |
325 | // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars | ||
326 | asset.ID = asset.FullID.ToString(); | ||
327 | |||
325 | asset.Temporary = false; | 328 | asset.Temporary = false; |
326 | asset.Local = false; | 329 | asset.Local = false; |
327 | m_scene.AssetService.Store(asset); | 330 | m_scene.AssetService.Store(asset); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index befb076..794ee17 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | |||
@@ -6,7 +6,7 @@ | |||
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyrightD | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c215e3a..939d38a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -58,8 +58,6 @@ public sealed class BSCharacter : BSPhysObject | |||
58 | private bool _flying; | 58 | private bool _flying; |
59 | private bool _setAlwaysRun; | 59 | private bool _setAlwaysRun; |
60 | private bool _throttleUpdates; | 60 | private bool _throttleUpdates; |
61 | private bool _isColliding; | ||
62 | private bool _collidingObj; | ||
63 | private bool _floatOnWater; | 61 | private bool _floatOnWater; |
64 | private OMV.Vector3 _rotationalVelocity; | 62 | private OMV.Vector3 _rotationalVelocity; |
65 | private bool _kinematic; | 63 | private bool _kinematic; |
@@ -186,10 +184,6 @@ public sealed class BSCharacter : BSPhysObject | |||
186 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. | 184 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. |
187 | private void SetupMovementMotor() | 185 | private void SetupMovementMotor() |
188 | { | 186 | { |
189 | |||
190 | // Someday, use a PID motor for asymmetric speed up and slow down | ||
191 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
192 | |||
193 | // Infinite decay and timescale values so motor only changes current to target values. | 187 | // Infinite decay and timescale values so motor only changes current to target values. |
194 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | 188 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", |
195 | 0.2f, // time scale | 189 | 0.2f, // time scale |
@@ -216,25 +210,68 @@ public sealed class BSCharacter : BSPhysObject | |||
216 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. | 210 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. |
217 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; | 211 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; |
218 | 212 | ||
219 | /* | 213 | // Should we check for move force being small and forcing velocity to zero? |
220 | // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user | 214 | |
221 | float moveForceMagnitudeSquared = moveForce.LengthSquared(); | 215 | // Add special movement force to allow avatars to walk up stepped surfaces. |
222 | if (moveForceMagnitudeSquared < 0.0001) | 216 | moveForce += WalkUpStairs(); |
223 | { | 217 | |
224 | DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}", | 218 | DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); |
225 | LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce); | ||
226 | ForceVelocity = OMV.Vector3.Zero; | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | AddForce(moveForce, false, true); | ||
231 | } | ||
232 | */ | ||
233 | // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); | ||
234 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); | 219 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); |
235 | }); | 220 | }); |
236 | } | 221 | } |
237 | 222 | ||
223 | // Decide of the character is colliding with a low object and compute a force to pop the | ||
224 | // avatar up so it has a chance of walking up and over the low object. | ||
225 | private OMV.Vector3 WalkUpStairs() | ||
226 | { | ||
227 | OMV.Vector3 ret = OMV.Vector3.Zero; | ||
228 | |||
229 | // This test is done if moving forward, not flying and is colliding with something. | ||
230 | // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", | ||
231 | // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); | ||
232 | if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */) | ||
233 | { | ||
234 | // The range near the character's feet where we will consider stairs | ||
235 | float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; | ||
236 | float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; | ||
237 | |||
238 | // Look for a collision point that is near the character's feet and is oriented the same as the charactor is | ||
239 | foreach (KeyValuePair<uint, ContactPoint> kvp in CollisionsLastTick.m_objCollisionList) | ||
240 | { | ||
241 | // Don't care about collisions with the terrain | ||
242 | if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID) | ||
243 | { | ||
244 | OMV.Vector3 touchPosition = kvp.Value.Position; | ||
245 | // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}", | ||
246 | // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition); | ||
247 | if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) | ||
248 | { | ||
249 | // This contact is within the 'near the feet' range. | ||
250 | // The normal should be our contact point to the object so it is pointing away | ||
251 | // thus the difference between our facing orientation and the normal should be small. | ||
252 | OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation; | ||
253 | OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal); | ||
254 | float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); | ||
255 | if (diff < BSParam.AvatarStepApproachFactor) | ||
256 | { | ||
257 | // Found the stairs contact point. Push up a little to raise the character. | ||
258 | float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor; | ||
259 | ret = new OMV.Vector3(0f, 0f, upForce); | ||
260 | |||
261 | // Also move the avatar up for the new height | ||
262 | OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f); | ||
263 | ForcePosition = RawPosition + displacement; | ||
264 | } | ||
265 | DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}", | ||
266 | LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
238 | public override void RequestPhysicsterseUpdate() | 275 | public override void RequestPhysicsterseUpdate() |
239 | { | 276 | { |
240 | base.RequestPhysicsterseUpdate(); | 277 | base.RequestPhysicsterseUpdate(); |
@@ -344,13 +381,11 @@ public sealed class BSCharacter : BSPhysObject | |||
344 | } | 381 | } |
345 | set { | 382 | set { |
346 | _position = value; | 383 | _position = value; |
347 | PositionSanityCheck(); | ||
348 | 384 | ||
349 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() | 385 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() |
350 | { | 386 | { |
351 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 387 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
352 | if (PhysBody.HasPhysicalBody) | 388 | ForcePosition = _position; |
353 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
354 | }); | 389 | }); |
355 | } | 390 | } |
356 | } | 391 | } |
@@ -361,8 +396,11 @@ public sealed class BSCharacter : BSPhysObject | |||
361 | } | 396 | } |
362 | set { | 397 | set { |
363 | _position = value; | 398 | _position = value; |
364 | PositionSanityCheck(); | 399 | if (PhysBody.HasPhysicalBody) |
365 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 400 | { |
401 | PositionSanityCheck(); | ||
402 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
403 | } | ||
366 | } | 404 | } |
367 | } | 405 | } |
368 | 406 | ||
@@ -375,7 +413,7 @@ public sealed class BSCharacter : BSPhysObject | |||
375 | bool ret = false; | 413 | bool ret = false; |
376 | 414 | ||
377 | // TODO: check for out of bounds | 415 | // TODO: check for out of bounds |
378 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 416 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
379 | { | 417 | { |
380 | // The character is out of the known/simulated area. | 418 | // The character is out of the known/simulated area. |
381 | // Upper levels of code will handle the transition to other areas so, for | 419 | // Upper levels of code will handle the transition to other areas so, for |
@@ -384,7 +422,7 @@ public sealed class BSCharacter : BSPhysObject | |||
384 | } | 422 | } |
385 | 423 | ||
386 | // If below the ground, move the avatar up | 424 | // If below the ground, move the avatar up |
387 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); | 425 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); |
388 | if (Position.Z < terrainHeight) | 426 | if (Position.Z < terrainHeight) |
389 | { | 427 | { |
390 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 428 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
@@ -487,6 +525,11 @@ public sealed class BSCharacter : BSPhysObject | |||
487 | }); | 525 | }); |
488 | } | 526 | } |
489 | } | 527 | } |
528 | public override OMV.Vector3 RawVelocity | ||
529 | { | ||
530 | get { return _velocity; } | ||
531 | set { _velocity = value; } | ||
532 | } | ||
490 | // Directly setting velocity means this is what the user really wants now. | 533 | // Directly setting velocity means this is what the user really wants now. |
491 | public override OMV.Vector3 Velocity { | 534 | public override OMV.Vector3 Velocity { |
492 | get { return _velocity; } | 535 | get { return _velocity; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 13c2539..c34c05a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
137 | get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } | 137 | get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } |
138 | } | 138 | } |
139 | 139 | ||
140 | #region Vehicle parameter setting | ||
140 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) | 141 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) |
141 | { | 142 | { |
142 | VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); | 143 | VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); |
@@ -546,6 +547,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
546 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); | 547 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); |
547 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 548 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
548 | } | 549 | } |
550 | #endregion // Vehicle parameter setting | ||
549 | 551 | ||
550 | // Some of the properties of this prim may have changed. | 552 | // Some of the properties of this prim may have changed. |
551 | // Do any updating needed for a vehicle | 553 | // Do any updating needed for a vehicle |
@@ -854,6 +856,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
854 | // The movement computed in the linear motor is relative to the vehicle | 856 | // The movement computed in the linear motor is relative to the vehicle |
855 | // coordinates. Rotate the movement to world coordinates. | 857 | // coordinates. Rotate the movement to world coordinates. |
856 | linearMotorContribution *= VehicleOrientation; | 858 | linearMotorContribution *= VehicleOrientation; |
859 | // All the contributions after this are world relative (mostly Z modifications) | ||
857 | 860 | ||
858 | // ================================================================== | 861 | // ================================================================== |
859 | // Buoyancy: force to overcome gravity. | 862 | // Buoyancy: force to overcome gravity. |
@@ -925,7 +928,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
925 | // TODO: Consider taking the rotated size of the object or possibly casting a ray. | 928 | // TODO: Consider taking the rotated size of the object or possibly casting a ray. |
926 | if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) | 929 | if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) |
927 | { | 930 | { |
928 | // TODO: correct position by applying force rather than forcing position. | 931 | // Force position because applying force won't get the vehicle through the terrain |
929 | Vector3 newPosition = VehiclePosition; | 932 | Vector3 newPosition = VehiclePosition; |
930 | newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; | 933 | newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; |
931 | VehiclePosition = newPosition; | 934 | VehiclePosition = newPosition; |
@@ -980,14 +983,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
980 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; | 983 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; |
981 | 984 | ||
982 | // TODO: implement m_VhoverEfficiency correctly | 985 | // TODO: implement m_VhoverEfficiency correctly |
983 | if (Math.Abs(verticalError) > m_VhoverEfficiency) | 986 | ret = new Vector3(0f, 0f, verticalCorrectionVelocity); |
984 | { | ||
985 | ret = new Vector3(0f, 0f, verticalCorrectionVelocity); | ||
986 | } | ||
987 | } | 987 | } |
988 | 988 | ||
989 | VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", | 989 | VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}", |
990 | Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); | 990 | Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret); |
991 | } | 991 | } |
992 | 992 | ||
993 | return ret; | 993 | return ret; |
@@ -1109,6 +1109,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1109 | + deflectionContribution | 1109 | + deflectionContribution |
1110 | + bankingContribution; | 1110 | + bankingContribution; |
1111 | 1111 | ||
1112 | // Add of the above computation are made relative to vehicle coordinates. | ||
1113 | // Convert to world coordinates. | ||
1114 | m_lastAngularVelocity *= VehicleOrientation; | ||
1115 | |||
1112 | // ================================================================== | 1116 | // ================================================================== |
1113 | // Apply the correction velocity. | 1117 | // Apply the correction velocity. |
1114 | // TODO: Should this be applied as an angular force (torque)? | 1118 | // TODO: Should this be applied as an angular force (torque)? |
@@ -1220,19 +1224,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1220 | public Vector3 ComputeAngularDeflection() | 1224 | public Vector3 ComputeAngularDeflection() |
1221 | { | 1225 | { |
1222 | Vector3 ret = Vector3.Zero; | 1226 | Vector3 ret = Vector3.Zero; |
1223 | return ret; // DEBUG DEBUG DEBUG | 1227 | |
1224 | // Disable angular deflection for the moment. | ||
1225 | // Since angularMotorUp and angularDeflection are computed independently, they will calculate | 1228 | // Since angularMotorUp and angularDeflection are computed independently, they will calculate |
1226 | // approximately the same X or Y correction. When added together (when contributions are combined) | 1229 | // approximately the same X or Y correction. When added together (when contributions are combined) |
1227 | // this creates an over-correction and then wabbling as the target is overshot. | 1230 | // this creates an over-correction and then wabbling as the target is overshot. |
1228 | // TODO: rethink how the different correction computations inter-relate. | 1231 | // TODO: rethink how the different correction computations inter-relate. |
1229 | 1232 | ||
1230 | if (m_angularDeflectionEfficiency != 0) | 1233 | if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) |
1231 | { | 1234 | { |
1232 | // The direction the vehicle is moving | 1235 | // The direction the vehicle is moving |
1233 | Vector3 movingDirection = VehicleVelocity; | 1236 | Vector3 movingDirection = VehicleVelocity; |
1234 | movingDirection.Normalize(); | 1237 | movingDirection.Normalize(); |
1235 | 1238 | ||
1239 | // If the vehicle is going backward, it is still pointing forward | ||
1240 | movingDirection *= Math.Sign(VehicleForwardSpeed); | ||
1241 | |||
1236 | // The direction the vehicle is pointing | 1242 | // The direction the vehicle is pointing |
1237 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; | 1243 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; |
1238 | pointingDirection.Normalize(); | 1244 | pointingDirection.Normalize(); |
@@ -1241,6 +1247,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1241 | Vector3 deflectionError = movingDirection - pointingDirection; | 1247 | Vector3 deflectionError = movingDirection - pointingDirection; |
1242 | 1248 | ||
1243 | // Don't try to correct very large errors (not our job) | 1249 | // Don't try to correct very large errors (not our job) |
1250 | // if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X); | ||
1251 | // if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = PIOverTwo * Math.Sign(deflectionError.Y); | ||
1252 | // if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = PIOverTwo * Math.Sign(deflectionError.Z); | ||
1244 | if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; | 1253 | if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; |
1245 | if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; | 1254 | if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; |
1246 | if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; | 1255 | if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; |
@@ -1296,33 +1305,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1296 | 1305 | ||
1297 | if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1306 | if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1298 | { | 1307 | { |
1299 | // This works by rotating a unit vector to the orientation of the vehicle. The | 1308 | // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. |
1300 | // roll (tilt) will be Y component of a tilting Z vector (zero for no tilt | 1309 | // As the vehicle rolls to the right or left, the Y value will increase from |
1301 | // up to one for full over). | 1310 | // zero (straight up) to 1 or -1 (full tilt right or left) |
1302 | Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; | 1311 | Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; |
1303 | 1312 | ||
1304 | // Figure out the yaw value for this much roll. | 1313 | // Figure out the yaw value for this much roll. |
1305 | float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency; | 1314 | // Squared because that seems to give a good value |
1306 | // Keep the sign | 1315 | float yawAngle = (float)Math.Asin(rollComponents.Y * rollComponents.Y) * m_bankingEfficiency; |
1307 | if (rollComponents.Y < 0f) | ||
1308 | turnComponent = -turnComponent; | ||
1309 | |||
1310 | // TODO: there must be a better computation of the banking force. | ||
1311 | float bankingTurnForce = turnComponent; | ||
1312 | 1316 | ||
1313 | // actual error = static turn error + dynamic turn error | 1317 | // actual error = static turn error + dynamic turn error |
1314 | float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed; | 1318 | float mixedYawAngle = yawAngle * (1f - m_bankingMix) + yawAngle * m_bankingMix * VehicleForwardSpeed; |
1319 | |||
1315 | // TODO: the banking effect should not go to infinity but what to limit it to? | 1320 | // TODO: the banking effect should not go to infinity but what to limit it to? |
1316 | mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f); | 1321 | mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); |
1317 | 1322 | ||
1318 | // Build the force vector to change rotation from what it is to what it should be | 1323 | // Build the force vector to change rotation from what it is to what it should be |
1319 | ret.Z = -mixedBankingError; | 1324 | ret.Z = -mixedYawAngle; |
1320 | 1325 | ||
1321 | // Don't do it all at once. | 1326 | // Don't do it all at once. |
1322 | ret /= m_bankingTimescale; | 1327 | ret /= m_bankingTimescale; |
1323 | 1328 | ||
1324 | VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}", | 1329 | VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", |
1325 | Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret); | 1330 | Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, ret); |
1326 | } | 1331 | } |
1327 | return ret; | 1332 | return ret; |
1328 | } | 1333 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index b9bd0bf..23d573f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -75,6 +75,9 @@ public static class BSParam | |||
75 | public static float AvatarCapsuleDepth { get; private set; } | 75 | public static float AvatarCapsuleDepth { get; private set; } |
76 | public static float AvatarCapsuleHeight { get; private set; } | 76 | public static float AvatarCapsuleHeight { get; private set; } |
77 | public static float AvatarContactProcessingThreshold { get; private set; } | 77 | public static float AvatarContactProcessingThreshold { get; private set; } |
78 | public static float AvatarStepHeight { get; private set; } | ||
79 | public static float AvatarStepApproachFactor { get; private set; } | ||
80 | public static float AvatarStepForceFactor { get; private set; } | ||
78 | 81 | ||
79 | public static float VehicleAngularDamping { get; private set; } | 82 | public static float VehicleAngularDamping { get; private set; } |
80 | 83 | ||
@@ -403,6 +406,21 @@ public static class BSParam | |||
403 | (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, | 406 | (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, |
404 | (s) => { return AvatarContactProcessingThreshold; }, | 407 | (s) => { return AvatarContactProcessingThreshold; }, |
405 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), | 408 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), |
409 | new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", | ||
410 | 0.3f, | ||
411 | (s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); }, | ||
412 | (s) => { return AvatarStepHeight; }, | ||
413 | (s,p,l,v) => { AvatarStepHeight = v; } ), | ||
414 | new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", | ||
415 | 0.6f, | ||
416 | (s,cf,p,v) => { AvatarStepApproachFactor = cf.GetFloat(p, v); }, | ||
417 | (s) => { return AvatarStepApproachFactor; }, | ||
418 | (s,p,l,v) => { AvatarStepApproachFactor = v; } ), | ||
419 | new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", | ||
420 | 2.0f, | ||
421 | (s,cf,p,v) => { AvatarStepForceFactor = cf.GetFloat(p, v); }, | ||
422 | (s) => { return AvatarStepForceFactor; }, | ||
423 | (s,p,l,v) => { AvatarStepForceFactor = v; } ), | ||
406 | 424 | ||
407 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", | 425 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", |
408 | 0.95f, | 426 | 0.95f, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 534f929..e8575f6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -79,6 +79,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
79 | Material = MaterialAttributes.Material.Wood; | 79 | Material = MaterialAttributes.Material.Wood; |
80 | 80 | ||
81 | CollisionCollection = new CollisionEventUpdate(); | 81 | CollisionCollection = new CollisionEventUpdate(); |
82 | CollisionsLastTick = CollisionCollection; | ||
82 | SubscribedEventsMs = 0; | 83 | SubscribedEventsMs = 0; |
83 | CollidingStep = 0; | 84 | CollidingStep = 0; |
84 | CollidingGroundStep = 0; | 85 | CollidingGroundStep = 0; |
@@ -159,6 +160,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
159 | public abstract OMV.Quaternion ForceOrientation { get; set; } | 160 | public abstract OMV.Quaternion ForceOrientation { get; set; } |
160 | 161 | ||
161 | // The system is telling us the velocity it wants to move at. | 162 | // The system is telling us the velocity it wants to move at. |
163 | // Velocity in world coordinates. | ||
162 | // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor | 164 | // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor |
163 | public override OMV.Vector3 TargetVelocity | 165 | public override OMV.Vector3 TargetVelocity |
164 | { | 166 | { |
@@ -169,6 +171,15 @@ public abstract class BSPhysObject : PhysicsActor | |||
169 | Velocity = value; | 171 | Velocity = value; |
170 | } | 172 | } |
171 | } | 173 | } |
174 | public virtual float TargetSpeed | ||
175 | { | ||
176 | get | ||
177 | { | ||
178 | OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); | ||
179 | return characterOrientedVelocity.X; | ||
180 | } | ||
181 | } | ||
182 | public abstract OMV.Vector3 RawVelocity { get; set; } | ||
172 | public abstract OMV.Vector3 ForceVelocity { get; set; } | 183 | public abstract OMV.Vector3 ForceVelocity { get; set; } |
173 | 184 | ||
174 | public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } | 185 | public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } |
@@ -177,6 +188,15 @@ public abstract class BSPhysObject : PhysicsActor | |||
177 | 188 | ||
178 | public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } | 189 | public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } |
179 | 190 | ||
191 | public virtual float ForwardSpeed | ||
192 | { | ||
193 | get | ||
194 | { | ||
195 | OMV.Vector3 characterOrientedVelocity = RawVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); | ||
196 | return characterOrientedVelocity.X; | ||
197 | } | ||
198 | } | ||
199 | |||
180 | #region Collisions | 200 | #region Collisions |
181 | 201 | ||
182 | // Requested number of milliseconds between collision events. Zero means disabled. | 202 | // Requested number of milliseconds between collision events. Zero means disabled. |
@@ -223,9 +243,13 @@ public abstract class BSPhysObject : PhysicsActor | |||
223 | 243 | ||
224 | // The collisions that have been collected this tick | 244 | // The collisions that have been collected this tick |
225 | protected CollisionEventUpdate CollisionCollection; | 245 | protected CollisionEventUpdate CollisionCollection; |
246 | // Remember collisions from last tick for fancy collision based actions | ||
247 | // (like a BSCharacter walking up stairs). | ||
248 | protected CollisionEventUpdate CollisionsLastTick; | ||
226 | 249 | ||
227 | // The simulation step is telling this object about a collision. | 250 | // The simulation step is telling this object about a collision. |
228 | // Return 'true' if a collision was processed and should be sent up. | 251 | // Return 'true' if a collision was processed and should be sent up. |
252 | // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. | ||
229 | // Called at taint time from within the Step() function | 253 | // Called at taint time from within the Step() function |
230 | public virtual bool Collide(uint collidingWith, BSPhysObject collidee, | 254 | public virtual bool Collide(uint collidingWith, BSPhysObject collidee, |
231 | OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) | 255 | OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) |
@@ -286,6 +310,9 @@ public abstract class BSPhysObject : PhysicsActor | |||
286 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); | 310 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); |
287 | base.SendCollisionUpdate(CollisionCollection); | 311 | base.SendCollisionUpdate(CollisionCollection); |
288 | 312 | ||
313 | // Remember the collisions from this tick for some collision specific processing. | ||
314 | CollisionsLastTick = CollisionCollection; | ||
315 | |||
289 | // The CollisionCollection instance is passed around in the simulator. | 316 | // The CollisionCollection instance is passed around in the simulator. |
290 | // Make sure we don't have a handle to that one and that a new one is used for next time. | 317 | // Make sure we don't have a handle to that one and that a new one is used for next time. |
291 | // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, | 318 | // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 94b63e5..400d5d6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -562,7 +562,7 @@ public sealed class BSPrim : BSPhysObject | |||
562 | } | 562 | } |
563 | return; | 563 | return; |
564 | } | 564 | } |
565 | public OMV.Vector3 RawVelocity | 565 | public override OMV.Vector3 RawVelocity |
566 | { | 566 | { |
567 | get { return _velocity; } | 567 | get { return _velocity; } |
568 | set { _velocity = value; } | 568 | set { _velocity = value; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index c75eb9b..ee18379 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -27,24 +27,19 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
31 | using System.Text; | 30 | using System.Text; |
32 | 31 | ||
32 | using OMV = OpenMetaverse; | ||
33 | |||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | 34 | namespace OpenSim.Region.Physics.BulletSPlugin |
34 | { | 35 | { |
35 | public abstract class BSShape | 36 | public abstract class BSShape |
36 | { | 37 | { |
37 | public IntPtr ptr { get; set; } | ||
38 | public BSPhysicsShapeType type { get; set; } | ||
39 | public System.UInt64 key { get; set; } | ||
40 | public int referenceCount { get; set; } | 38 | public int referenceCount { get; set; } |
41 | public DateTime lastReferenced { get; set; } | 39 | public DateTime lastReferenced { get; set; } |
42 | 40 | ||
43 | public BSShape() | 41 | public BSShape() |
44 | { | 42 | { |
45 | ptr = IntPtr.Zero; | ||
46 | type = BSPhysicsShapeType.SHAPE_UNKNOWN; | ||
47 | key = 0; | ||
48 | referenceCount = 0; | 43 | referenceCount = 0; |
49 | lastReferenced = DateTime.Now; | 44 | lastReferenced = DateTime.Now; |
50 | } | 45 | } |
@@ -63,7 +58,7 @@ public abstract class BSShape | |||
63 | } | 58 | } |
64 | 59 | ||
65 | // Compound shapes are handled special as they are rebuilt from scratch. | 60 | // Compound shapes are handled special as they are rebuilt from scratch. |
66 | // This isn't too great a hardship since most of the child shapes will already been created. | 61 | // This isn't too great a hardship since most of the child shapes will have already been created. |
67 | if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) | 62 | if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) |
68 | { | 63 | { |
69 | // Getting a reference to a compound shape gets you the compound shape with the root prim shape added | 64 | // Getting a reference to a compound shape gets you the compound shape with the root prim shape added |
@@ -71,6 +66,14 @@ public abstract class BSShape | |||
71 | physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); | 66 | physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); |
72 | } | 67 | } |
73 | 68 | ||
69 | // Avatars have their own unique shape | ||
70 | if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR) | ||
71 | { | ||
72 | // Getting a reference to a compound shape gets you the compound shape with the root prim shape added | ||
73 | ret = BSShapeAvatar.GetReference(prim); | ||
74 | physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret); | ||
75 | } | ||
76 | |||
74 | if (ret == null) | 77 | if (ret == null) |
75 | ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); | 78 | ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); |
76 | 79 | ||
@@ -92,9 +95,9 @@ public abstract class BSShape | |||
92 | // protected abstract static BSShape GetReference(); | 95 | // protected abstract static BSShape GetReference(); |
93 | 96 | ||
94 | // Returns a string for debugging that uniquily identifies the memory used by this instance | 97 | // Returns a string for debugging that uniquily identifies the memory used by this instance |
95 | public string AddrString | 98 | public virtual string AddrString |
96 | { | 99 | { |
97 | get { return ptr.ToString("X"); } | 100 | get { return "unknown"; } |
98 | } | 101 | } |
99 | 102 | ||
100 | public override string ToString() | 103 | public override string ToString() |
@@ -102,10 +105,6 @@ public abstract class BSShape | |||
102 | StringBuilder buff = new StringBuilder(); | 105 | StringBuilder buff = new StringBuilder(); |
103 | buff.Append("<p="); | 106 | buff.Append("<p="); |
104 | buff.Append(AddrString); | 107 | buff.Append(AddrString); |
105 | buff.Append(",s="); | ||
106 | buff.Append(type.ToString()); | ||
107 | buff.Append(",k="); | ||
108 | buff.Append(key.ToString("X")); | ||
109 | buff.Append(",c="); | 108 | buff.Append(",c="); |
110 | buff.Append(referenceCount.ToString()); | 109 | buff.Append(referenceCount.ToString()); |
111 | buff.Append(">"); | 110 | buff.Append(">"); |
@@ -228,5 +227,131 @@ public class BSShapeAvatar : BSShape | |||
228 | return new BSShapeNull(); | 227 | return new BSShapeNull(); |
229 | } | 228 | } |
230 | public override void Dereference(BSScene physicsScene) { } | 229 | public override void Dereference(BSScene physicsScene) { } |
230 | |||
231 | // From the front: | ||
232 | // A---A | ||
233 | // / \ | ||
234 | // B-------B | ||
235 | // / \ +Z | ||
236 | // C-----------C | | ||
237 | // \ / -Y --+-- +Y | ||
238 | // \ / | | ||
239 | // \ / -Z | ||
240 | // D-----D | ||
241 | // \ / | ||
242 | // E-E | ||
243 | |||
244 | // From the top A and E are just lines. | ||
245 | // B, C and D are hexagons: | ||
246 | // | ||
247 | // C1--C2 +X | ||
248 | // / \ | | ||
249 | // C0 C3 -Y --+-- +Y | ||
250 | // \ / | | ||
251 | // C5--C4 -X | ||
252 | |||
253 | // Zero goes directly through the middle so the offsets are from that middle axis | ||
254 | // and up and down from a middle horizon (A and E are the same distance from the zero). | ||
255 | // The height, width and depth is one. All scaling is done by the simulator. | ||
256 | |||
257 | // Z component -- how far the level is from the middle zero | ||
258 | private const float Aup = 0.5f; | ||
259 | private const float Bup = 0.4f; | ||
260 | private const float Cup = 0.3f; | ||
261 | private const float Dup = -0.4f; | ||
262 | private const float Eup = -0.5f; | ||
263 | |||
264 | // Y component -- distance from center to x0 and x3 | ||
265 | private const float Awid = 0.25f; | ||
266 | private const float Bwid = 0.3f; | ||
267 | private const float Cwid = 0.5f; | ||
268 | private const float Dwid = 0.3f; | ||
269 | private const float Ewid = 0.2f; | ||
270 | |||
271 | // Y component -- distance from center to x1, x2, x4 and x5 | ||
272 | private const float Afwid = 0.0f; | ||
273 | private const float Bfwid = 0.2f; | ||
274 | private const float Cfwid = 0.4f; | ||
275 | private const float Dfwid = 0.2f; | ||
276 | private const float Efwid = 0.0f; | ||
277 | |||
278 | // X component -- distance from zero to the front or back of a level | ||
279 | private const float Adep = 0f; | ||
280 | private const float Bdep = 0.3f; | ||
281 | private const float Cdep = 0.5f; | ||
282 | private const float Ddep = 0.2f; | ||
283 | private const float Edep = 0f; | ||
284 | |||
285 | private OMV.Vector3[] avatarVertices = { | ||
286 | new OMV.Vector3( 0.0f, -Awid, Aup), // A0 | ||
287 | new OMV.Vector3( 0.0f, +Awid, Aup), // A3 | ||
288 | |||
289 | new OMV.Vector3( 0.0f, -Bwid, Bup), // B0 | ||
290 | new OMV.Vector3(+Bdep, -Bfwid, Bup), // B1 | ||
291 | new OMV.Vector3(+Bdep, +Bfwid, Bup), // B2 | ||
292 | new OMV.Vector3( 0.0f, +Bwid, Bup), // B3 | ||
293 | new OMV.Vector3(-Bdep, +Bfwid, Bup), // B4 | ||
294 | new OMV.Vector3(-Bdep, -Bfwid, Bup), // B5 | ||
295 | |||
296 | new OMV.Vector3( 0.0f, -Cwid, Cup), // C0 | ||
297 | new OMV.Vector3(+Cdep, -Cfwid, Cup), // C1 | ||
298 | new OMV.Vector3(+Cdep, +Cfwid, Cup), // C2 | ||
299 | new OMV.Vector3( 0.0f, +Cwid, Cup), // C3 | ||
300 | new OMV.Vector3(-Cdep, +Cfwid, Cup), // C4 | ||
301 | new OMV.Vector3(-Cdep, -Cfwid, Cup), // C5 | ||
302 | |||
303 | new OMV.Vector3( 0.0f, -Dwid, Dup), // D0 | ||
304 | new OMV.Vector3(+Ddep, -Dfwid, Dup), // D1 | ||
305 | new OMV.Vector3(+Ddep, +Dfwid, Dup), // D2 | ||
306 | new OMV.Vector3( 0.0f, +Dwid, Dup), // D3 | ||
307 | new OMV.Vector3(-Ddep, +Dfwid, Dup), // D4 | ||
308 | new OMV.Vector3(-Ddep, -Dfwid, Dup), // D5 | ||
309 | |||
310 | new OMV.Vector3( 0.0f, -Ewid, Eup), // E0 | ||
311 | new OMV.Vector3( 0.0f, +Ewid, Eup), // E3 | ||
312 | }; | ||
313 | |||
314 | // Offsets of the vertices in the vertices array | ||
315 | private enum Ind : int | ||
316 | { | ||
317 | A0, A3, | ||
318 | B0, B1, B2, B3, B4, B5, | ||
319 | C0, C1, C2, C3, C4, C5, | ||
320 | D0, D1, D2, D3, D4, D5, | ||
321 | E0, E3 | ||
322 | } | ||
323 | |||
324 | // Comments specify trianges and quads in clockwise direction | ||
325 | private Ind[] avatarIndices = { | ||
326 | Ind.A0, Ind.B0, Ind.B1, // A0,B0,B1 | ||
327 | Ind.A0, Ind.B1, Ind.B2, Ind.B2, Ind.A3, Ind.A0, // A0,B1,B2,A3 | ||
328 | Ind.A3, Ind.B2, Ind.B3, // A3,B2,B3 | ||
329 | Ind.A3, Ind.B3, Ind.B4, // A3,B3,B4 | ||
330 | Ind.A3, Ind.B4, Ind.B5, Ind.B5, Ind.A0, Ind.A3, // A3,B4,B5,A0 | ||
331 | Ind.A0, Ind.B5, Ind.B0, // A0,B5,B0 | ||
332 | |||
333 | Ind.B0, Ind.C0, Ind.C1, Ind.C1, Ind.B1, Ind.B0, // B0,C0,C1,B1 | ||
334 | Ind.B1, Ind.C1, Ind.C2, Ind.C2, Ind.B2, Ind.B1, // B1,C1,C2,B2 | ||
335 | Ind.B2, Ind.C2, Ind.C3, Ind.C3, Ind.B3, Ind.B2, // B2,C2,C3,B3 | ||
336 | Ind.B3, Ind.C3, Ind.C4, Ind.C4, Ind.B4, Ind.B3, // B3,C3,C4,B4 | ||
337 | Ind.B4, Ind.C4, Ind.C5, Ind.C5, Ind.B5, Ind.B4, // B4,C4,C5,B5 | ||
338 | Ind.B5, Ind.C5, Ind.C0, Ind.C0, Ind.B0, Ind.B5, // B5,C5,C0,B0 | ||
339 | |||
340 | Ind.C0, Ind.D0, Ind.D1, Ind.D1, Ind.C1, Ind.C0, // C0,D0,D1,C1 | ||
341 | Ind.C1, Ind.D1, Ind.D2, Ind.D2, Ind.C2, Ind.C1, // C1,D1,D2,C2 | ||
342 | Ind.C2, Ind.D2, Ind.D3, Ind.D3, Ind.C3, Ind.C2, // C2,D2,D3,C3 | ||
343 | Ind.C3, Ind.D3, Ind.D4, Ind.D4, Ind.C4, Ind.C3, // C3,D3,D4,C4 | ||
344 | Ind.C4, Ind.D4, Ind.D5, Ind.D5, Ind.C5, Ind.C4, // C4,D4,D5,C5 | ||
345 | Ind.C5, Ind.D5, Ind.D0, Ind.D0, Ind.C0, Ind.C5, // C5,D5,D0,C0 | ||
346 | |||
347 | Ind.E0, Ind.D0, Ind.D1, // E0,D0,D1 | ||
348 | Ind.E0, Ind.D1, Ind.D2, Ind.D2, Ind.E3, Ind.E0, // E0,D1,D2,E3 | ||
349 | Ind.E3, Ind.D2, Ind.D3, // E3,D2,D3 | ||
350 | Ind.E3, Ind.D3, Ind.D4, // E3,D3,D4 | ||
351 | Ind.E3, Ind.D4, Ind.D5, Ind.D5, Ind.E0, Ind.E3, // E3,D4,D5,E0 | ||
352 | Ind.E0, Ind.D5, Ind.D0, // E0,D5,D0 | ||
353 | |||
354 | }; | ||
355 | |||
231 | } | 356 | } |
232 | } | 357 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 1d55ce3..8244f02 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | |||
@@ -142,6 +142,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
142 | PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody); | 142 | PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody); |
143 | // Frees both the body and the shape. | 143 | // Frees both the body and the shape. |
144 | PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody); | 144 | PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody); |
145 | m_terrainBody.Clear(); | ||
146 | m_terrainShape.Clear(); | ||
145 | } | 147 | } |
146 | } | 148 | } |
147 | 149 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 662dd68..c7a2f7e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs | |||
@@ -114,8 +114,10 @@ public class BulletShape | |||
114 | 114 | ||
115 | public virtual void Clear() { } | 115 | public virtual void Clear() { } |
116 | public virtual bool HasPhysicalShape { get { return false; } } | 116 | public virtual bool HasPhysicalShape { get { return false; } } |
117 | |||
117 | // Make another reference to this physical object. | 118 | // Make another reference to this physical object. |
118 | public virtual BulletShape Clone() { return new BulletShape(); } | 119 | public virtual BulletShape Clone() { return new BulletShape(); } |
120 | |||
119 | // Return 'true' if this and other refer to the same physical object | 121 | // Return 'true' if this and other refer to the same physical object |
120 | public virtual bool ReferenceSame(BulletShape xx) { return false; } | 122 | public virtual bool ReferenceSame(BulletShape xx) { return false; } |
121 | 123 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index facf720..29bd4e4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -1,11 +1,9 @@ | |||
1 | CURRENT PRIORITIES | 1 | CURRENT PRIORITIES |
2 | ================================================= | 2 | ================================================= |
3 | Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) | 3 | Avatars walking up stairs (HALF DONE) |
4 | Meshes rendering as bounding boxes | ||
5 | llMoveToTarget | ||
6 | Vehicle movement on terrain smoothness | 4 | Vehicle movement on terrain smoothness |
7 | limitMotorUp calibration (more down?) | 5 | limitMotorUp calibration (more down?) |
8 | Preferred orientatino angular correction fix | 6 | Preferred orientation angular correction fix |
9 | Surfboard go wonky when turning | 7 | Surfboard go wonky when turning |
10 | Angular motor direction is global coordinates rather than local coordinates? | 8 | Angular motor direction is global coordinates rather than local coordinates? |
11 | Boats float low in the water | 9 | Boats float low in the water |
@@ -90,6 +88,8 @@ setForce should set a constant force. Different than AddImpulse. | |||
90 | Implement raycast. | 88 | Implement raycast. |
91 | Implement ShapeCollection.Dispose() | 89 | Implement ShapeCollection.Dispose() |
92 | Implement water as a plain so raycasting and collisions can happen with same. | 90 | Implement water as a plain so raycasting and collisions can happen with same. |
91 | Add collision penetration return | ||
92 | Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance() | ||
93 | Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE | 93 | Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE |
94 | Also osGetPhysicsEngineVerion() maybe. | 94 | Also osGetPhysicsEngineVerion() maybe. |
95 | Linkset.Position and Linkset.Orientation requre rewrite to properly return | 95 | Linkset.Position and Linkset.Orientation requre rewrite to properly return |
@@ -135,6 +135,9 @@ Eliminate collisions between objects in a linkset. (LinksetConstraint) | |||
135 | 135 | ||
136 | MORE | 136 | MORE |
137 | ====================================================== | 137 | ====================================================== |
138 | 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? | ||
140 | There is some problem with meshes and collisions | ||
138 | Test avatar walking up stairs. How does compare with SL. | 141 | Test avatar walking up stairs. How does compare with SL. |
139 | Radius of the capsule affects ability to climb edges. | 142 | Radius of the capsule affects ability to climb edges. |
140 | Debounce avatar contact so legs don't keep folding up when standing. | 143 | Debounce avatar contact so legs don't keep folding up when standing. |
@@ -274,3 +277,8 @@ llSetBuoyancy() (DONE) | |||
274 | (Resolution: Bullet resets object gravity when added to world. Moved set gravity) | 277 | (Resolution: Bullet resets object gravity when added to world. Moved set gravity) |
275 | Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE) | 278 | Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE) |
276 | (Resolution: set default density to 3.5 (from 60) which is closer to SL) | 279 | (Resolution: set default density to 3.5 (from 60) which is closer to SL) |
280 | Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) | ||
281 | (Resolution: added BSAPITemplate and then interfaces for C++ Bullet and C# BulletXNA | ||
282 | 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) | ||
284 | llMoveToTarget (Resolution: added simple motor to update the position.) | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 4dd795d..d3ef378 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs | |||
@@ -42,6 +42,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
42 | { | 42 | { |
43 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 43 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | 44 | ||
45 | /// <summary> | ||
46 | /// Used by one-off and repeated sensors | ||
47 | /// </summary> | ||
48 | public class SensorInfo | ||
49 | { | ||
50 | public uint localID; | ||
51 | public UUID itemID; | ||
52 | public double interval; | ||
53 | public DateTime next; | ||
54 | |||
55 | public string name; | ||
56 | public UUID keyID; | ||
57 | public int type; | ||
58 | public double range; | ||
59 | public double arc; | ||
60 | public SceneObjectPart host; | ||
61 | |||
62 | public SensorInfo Clone() | ||
63 | { | ||
64 | return (SensorInfo)this.MemberwiseClone(); | ||
65 | } | ||
66 | } | ||
67 | |||
45 | public AsyncCommandManager m_CmdManager; | 68 | public AsyncCommandManager m_CmdManager; |
46 | 69 | ||
47 | /// <summary> | 70 | /// <summary> |
@@ -78,24 +101,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
78 | private int maximumToReturn = 16; | 101 | private int maximumToReturn = 16; |
79 | 102 | ||
80 | // | 103 | // |
81 | // SenseRepeater and Sensors | ||
82 | // | ||
83 | private class SenseRepeatClass | ||
84 | { | ||
85 | public uint localID; | ||
86 | public UUID itemID; | ||
87 | public double interval; | ||
88 | public DateTime next; | ||
89 | |||
90 | public string name; | ||
91 | public UUID keyID; | ||
92 | public int type; | ||
93 | public double range; | ||
94 | public double arc; | ||
95 | public SceneObjectPart host; | ||
96 | } | ||
97 | |||
98 | // | ||
99 | // Sensed entity | 104 | // Sensed entity |
100 | // | 105 | // |
101 | private class SensedEntity : IComparable | 106 | private class SensedEntity : IComparable |
@@ -127,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
127 | /// | 132 | /// |
128 | /// Always lock SenseRepeatListLock when updating this list. | 133 | /// Always lock SenseRepeatListLock when updating this list. |
129 | /// </remarks> | 134 | /// </remarks> |
130 | private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>(); | 135 | private List<SensorInfo> SenseRepeaters = new List<SensorInfo>(); |
131 | private object SenseRepeatListLock = new object(); | 136 | private object SenseRepeatListLock = new object(); |
132 | 137 | ||
133 | public void SetSenseRepeatEvent(uint m_localID, UUID m_itemID, | 138 | public void SetSenseRepeatEvent(uint m_localID, UUID m_itemID, |
@@ -141,7 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
141 | return; | 146 | return; |
142 | 147 | ||
143 | // Add to timer | 148 | // Add to timer |
144 | SenseRepeatClass ts = new SenseRepeatClass(); | 149 | SensorInfo ts = new SensorInfo(); |
145 | ts.localID = m_localID; | 150 | ts.localID = m_localID; |
146 | ts.itemID = m_itemID; | 151 | ts.itemID = m_itemID; |
147 | ts.interval = sec; | 152 | ts.interval = sec; |
@@ -160,11 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
160 | AddSenseRepeater(ts); | 165 | AddSenseRepeater(ts); |
161 | } | 166 | } |
162 | 167 | ||
163 | private void AddSenseRepeater(SenseRepeatClass senseRepeater) | 168 | private void AddSenseRepeater(SensorInfo senseRepeater) |
164 | { | 169 | { |
165 | lock (SenseRepeatListLock) | 170 | lock (SenseRepeatListLock) |
166 | { | 171 | { |
167 | List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>(SenseRepeaters); | 172 | List<SensorInfo> newSenseRepeaters = new List<SensorInfo>(SenseRepeaters); |
168 | newSenseRepeaters.Add(senseRepeater); | 173 | newSenseRepeaters.Add(senseRepeater); |
169 | SenseRepeaters = newSenseRepeaters; | 174 | SenseRepeaters = newSenseRepeaters; |
170 | } | 175 | } |
@@ -175,8 +180,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
175 | // Remove from timer | 180 | // Remove from timer |
176 | lock (SenseRepeatListLock) | 181 | lock (SenseRepeatListLock) |
177 | { | 182 | { |
178 | List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>(); | 183 | List<SensorInfo> newSenseRepeaters = new List<SensorInfo>(); |
179 | foreach (SenseRepeatClass ts in SenseRepeaters) | 184 | foreach (SensorInfo ts in SenseRepeaters) |
180 | { | 185 | { |
181 | if (ts.localID != m_localID || ts.itemID != m_itemID) | 186 | if (ts.localID != m_localID || ts.itemID != m_itemID) |
182 | { | 187 | { |
@@ -191,7 +196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
191 | public void CheckSenseRepeaterEvents() | 196 | public void CheckSenseRepeaterEvents() |
192 | { | 197 | { |
193 | // Go through all timers | 198 | // Go through all timers |
194 | foreach (SenseRepeatClass ts in SenseRepeaters) | 199 | foreach (SensorInfo ts in SenseRepeaters) |
195 | { | 200 | { |
196 | // Time has passed? | 201 | // Time has passed? |
197 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) | 202 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) |
@@ -208,7 +213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
208 | double range, double arc, SceneObjectPart host) | 213 | double range, double arc, SceneObjectPart host) |
209 | { | 214 | { |
210 | // Add to timer | 215 | // Add to timer |
211 | SenseRepeatClass ts = new SenseRepeatClass(); | 216 | SensorInfo ts = new SensorInfo(); |
212 | ts.localID = m_localID; | 217 | ts.localID = m_localID; |
213 | ts.itemID = m_itemID; | 218 | ts.itemID = m_itemID; |
214 | ts.interval = 0; | 219 | ts.interval = 0; |
@@ -224,7 +229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
224 | SensorSweep(ts); | 229 | SensorSweep(ts); |
225 | } | 230 | } |
226 | 231 | ||
227 | private void SensorSweep(SenseRepeatClass ts) | 232 | private void SensorSweep(SensorInfo ts) |
228 | { | 233 | { |
229 | if (ts.host == null) | 234 | if (ts.host == null) |
230 | { | 235 | { |
@@ -300,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
300 | } | 305 | } |
301 | } | 306 | } |
302 | 307 | ||
303 | private List<SensedEntity> doObjectSensor(SenseRepeatClass ts) | 308 | private List<SensedEntity> doObjectSensor(SensorInfo ts) |
304 | { | 309 | { |
305 | List<EntityBase> Entities; | 310 | List<EntityBase> Entities; |
306 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); | 311 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); |
@@ -451,7 +456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
451 | return sensedEntities; | 456 | return sensedEntities; |
452 | } | 457 | } |
453 | 458 | ||
454 | private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) | 459 | private List<SensedEntity> doAgentSensor(SensorInfo ts) |
455 | { | 460 | { |
456 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); | 461 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); |
457 | 462 | ||
@@ -630,7 +635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
630 | { | 635 | { |
631 | List<Object> data = new List<Object>(); | 636 | List<Object> data = new List<Object>(); |
632 | 637 | ||
633 | foreach (SenseRepeatClass ts in SenseRepeaters) | 638 | foreach (SensorInfo ts in SenseRepeaters) |
634 | { | 639 | { |
635 | if (ts.itemID == itemID) | 640 | if (ts.itemID == itemID) |
636 | { | 641 | { |
@@ -660,7 +665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
660 | 665 | ||
661 | while (idx < data.Length) | 666 | while (idx < data.Length) |
662 | { | 667 | { |
663 | SenseRepeatClass ts = new SenseRepeatClass(); | 668 | SensorInfo ts = new SensorInfo(); |
664 | 669 | ||
665 | ts.localID = localID; | 670 | ts.localID = localID; |
666 | ts.itemID = itemID; | 671 | ts.itemID = itemID; |
@@ -681,5 +686,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
681 | idx += 6; | 686 | idx += 6; |
682 | } | 687 | } |
683 | } | 688 | } |
689 | |||
690 | public List<SensorInfo> GetSensorInfo() | ||
691 | { | ||
692 | List<SensorInfo> retList = new List<SensorInfo>(); | ||
693 | |||
694 | lock (SenseRepeatListLock) | ||
695 | { | ||
696 | foreach (SensorInfo i in SenseRepeaters) | ||
697 | retList.Add(i.Clone()); | ||
698 | } | ||
699 | |||
700 | return retList; | ||
701 | } | ||
684 | } | 702 | } |
685 | } | 703 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs index 9ee6946..68aacd2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs | |||
@@ -35,6 +35,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
35 | { | 35 | { |
36 | public class Timer | 36 | public class Timer |
37 | { | 37 | { |
38 | public class TimerInfo | ||
39 | { | ||
40 | public uint localID; | ||
41 | public UUID itemID; | ||
42 | //public double interval; | ||
43 | public long interval; | ||
44 | //public DateTime next; | ||
45 | public long next; | ||
46 | |||
47 | public TimerInfo Clone() | ||
48 | { | ||
49 | return (TimerInfo)this.MemberwiseClone(); | ||
50 | } | ||
51 | } | ||
52 | |||
38 | public AsyncCommandManager m_CmdManager; | 53 | public AsyncCommandManager m_CmdManager; |
39 | 54 | ||
40 | public int TimersCount | 55 | public int TimersCount |
@@ -59,17 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
59 | return localID.ToString() + itemID.ToString(); | 74 | return localID.ToString() + itemID.ToString(); |
60 | } | 75 | } |
61 | 76 | ||
62 | private class TimerClass | 77 | private Dictionary<string,TimerInfo> Timers = new Dictionary<string,TimerInfo>(); |
63 | { | ||
64 | public uint localID; | ||
65 | public UUID itemID; | ||
66 | //public double interval; | ||
67 | public long interval; | ||
68 | //public DateTime next; | ||
69 | public long next; | ||
70 | } | ||
71 | |||
72 | private Dictionary<string,TimerClass> Timers = new Dictionary<string,TimerClass>(); | ||
73 | private object TimerListLock = new object(); | 78 | private object TimerListLock = new object(); |
74 | 79 | ||
75 | public void SetTimerEvent(uint m_localID, UUID m_itemID, double sec) | 80 | public void SetTimerEvent(uint m_localID, UUID m_itemID, double sec) |
@@ -81,7 +86,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
81 | } | 86 | } |
82 | 87 | ||
83 | // Add to timer | 88 | // Add to timer |
84 | TimerClass ts = new TimerClass(); | 89 | TimerInfo ts = new TimerInfo(); |
85 | ts.localID = m_localID; | 90 | ts.localID = m_localID; |
86 | ts.itemID = m_itemID; | 91 | ts.itemID = m_itemID; |
87 | ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait | 92 | ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait |
@@ -118,14 +123,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
118 | if (Timers.Count == 0) | 123 | if (Timers.Count == 0) |
119 | return; | 124 | return; |
120 | 125 | ||
121 | Dictionary<string, TimerClass>.ValueCollection tvals; | 126 | Dictionary<string, TimerInfo>.ValueCollection tvals; |
122 | lock (TimerListLock) | 127 | lock (TimerListLock) |
123 | { | 128 | { |
124 | // Go through all timers | 129 | // Go through all timers |
125 | tvals = Timers.Values; | 130 | tvals = Timers.Values; |
126 | } | 131 | } |
127 | 132 | ||
128 | foreach (TimerClass ts in tvals) | 133 | foreach (TimerInfo ts in tvals) |
129 | { | 134 | { |
130 | // Time has passed? | 135 | // Time has passed? |
131 | if (ts.next < DateTime.Now.Ticks) | 136 | if (ts.next < DateTime.Now.Ticks) |
@@ -149,8 +154,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
149 | 154 | ||
150 | lock (TimerListLock) | 155 | lock (TimerListLock) |
151 | { | 156 | { |
152 | Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; | 157 | Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; |
153 | foreach (TimerClass ts in tvals) | 158 | foreach (TimerInfo ts in tvals) |
154 | { | 159 | { |
155 | if (ts.itemID == itemID) | 160 | if (ts.itemID == itemID) |
156 | { | 161 | { |
@@ -169,7 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
169 | 174 | ||
170 | while (idx < data.Length) | 175 | while (idx < data.Length) |
171 | { | 176 | { |
172 | TimerClass ts = new TimerClass(); | 177 | TimerInfo ts = new TimerInfo(); |
173 | 178 | ||
174 | ts.localID = localID; | 179 | ts.localID = localID; |
175 | ts.itemID = itemID; | 180 | ts.itemID = itemID; |
@@ -183,5 +188,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
183 | } | 188 | } |
184 | } | 189 | } |
185 | } | 190 | } |
191 | |||
192 | public List<TimerInfo> GetTimersInfo() | ||
193 | { | ||
194 | List<TimerInfo> retList = new List<TimerInfo>(); | ||
195 | |||
196 | lock (TimerListLock) | ||
197 | { | ||
198 | foreach (TimerInfo i in Timers.Values) | ||
199 | retList.Add(i.Clone()); | ||
200 | } | ||
201 | |||
202 | return retList; | ||
203 | } | ||
186 | } | 204 | } |
187 | } | 205 | } |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs new file mode 100644 index 0000000..efb854d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Framework.Console; | ||
32 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
33 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
34 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; | ||
35 | |||
36 | namespace OpenSim.Region.ScriptEngine.XEngine | ||
37 | { | ||
38 | public class ScriptEngineConsoleCommands | ||
39 | { | ||
40 | IScriptEngine m_engine; | ||
41 | |||
42 | public ScriptEngineConsoleCommands(IScriptEngine engine) | ||
43 | { | ||
44 | m_engine = engine; | ||
45 | } | ||
46 | |||
47 | public void RegisterCommands() | ||
48 | { | ||
49 | MainConsole.Instance.Commands.AddCommand( | ||
50 | "Scripts", false, "show script sensors", "show script sensors", "Show script sensors information", | ||
51 | HandleShowSensors); | ||
52 | |||
53 | MainConsole.Instance.Commands.AddCommand( | ||
54 | "Scripts", false, "show script timers", "show script timers", "Show script sensors information", | ||
55 | HandleShowTimers); | ||
56 | } | ||
57 | |||
58 | private bool IsSceneSelected() | ||
59 | { | ||
60 | return MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World; | ||
61 | } | ||
62 | |||
63 | private void HandleShowSensors(string module, string[] cmdparams) | ||
64 | { | ||
65 | if (!IsSceneSelected()) | ||
66 | return; | ||
67 | |||
68 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(m_engine); | ||
69 | |||
70 | if (sr == null) | ||
71 | { | ||
72 | MainConsole.Instance.Output("Plugin not yet initialized"); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | List<SensorRepeat.SensorInfo> sensorInfo = sr.GetSensorInfo(); | ||
77 | |||
78 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
79 | cdt.AddColumn("Part name", 40); | ||
80 | cdt.AddColumn("Script item ID", 36); | ||
81 | cdt.AddColumn("Type", 4); | ||
82 | cdt.AddColumn("Interval", 8); | ||
83 | cdt.AddColumn("Range", 8); | ||
84 | cdt.AddColumn("Arc", 8); | ||
85 | |||
86 | foreach (SensorRepeat.SensorInfo s in sensorInfo) | ||
87 | { | ||
88 | cdt.AddRow(s.host.Name, s.itemID, s.type, s.interval, s.range, s.arc); | ||
89 | } | ||
90 | |||
91 | MainConsole.Instance.Output(cdt.ToString()); | ||
92 | MainConsole.Instance.OutputFormat("Total: {0}", sensorInfo.Count); | ||
93 | } | ||
94 | |||
95 | private void HandleShowTimers(string module, string[] cmdparams) | ||
96 | { | ||
97 | if (!IsSceneSelected()) | ||
98 | return; | ||
99 | |||
100 | Timer timerPlugin = AsyncCommandManager.GetTimerPlugin(m_engine); | ||
101 | |||
102 | if (timerPlugin == null) | ||
103 | { | ||
104 | MainConsole.Instance.Output("Plugin not yet initialized"); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | List<Timer.TimerInfo> timersInfo = timerPlugin.GetTimersInfo(); | ||
109 | |||
110 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
111 | cdt.AddColumn("Part local ID", 13); | ||
112 | cdt.AddColumn("Script item ID", 36); | ||
113 | cdt.AddColumn("Interval", 10); | ||
114 | cdt.AddColumn("Next", 8); | ||
115 | |||
116 | foreach (Timer.TimerInfo t in timersInfo) | ||
117 | { | ||
118 | // Convert from 100 ns ticks back to seconds | ||
119 | cdt.AddRow(t.localID, t.itemID, (double)t.interval / 10000000, t.next); | ||
120 | } | ||
121 | |||
122 | MainConsole.Instance.Output(cdt.ToString()); | ||
123 | MainConsole.Instance.OutputFormat("Total: {0}", timersInfo.Count); | ||
124 | } | ||
125 | } | ||
126 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 05dd7ab..34fcf0c 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -237,6 +237,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
237 | } | 237 | } |
238 | } | 238 | } |
239 | 239 | ||
240 | private ScriptEngineConsoleCommands m_consoleCommands; | ||
241 | |||
240 | public string ScriptEngineName | 242 | public string ScriptEngineName |
241 | { | 243 | { |
242 | get { return "XEngine"; } | 244 | get { return "XEngine"; } |
@@ -386,50 +388,53 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
386 | OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; | 388 | OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; |
387 | } | 389 | } |
388 | 390 | ||
391 | m_consoleCommands = new ScriptEngineConsoleCommands(this); | ||
392 | m_consoleCommands.RegisterCommands(); | ||
393 | |||
389 | MainConsole.Instance.Commands.AddCommand( | 394 | MainConsole.Instance.Commands.AddCommand( |
390 | "Scripts", false, "xengine status", "xengine status", "Show status information", | 395 | "Scripts", false, "xengine status", "xengine status", "Show status information", |
391 | "Show status information on the script engine.", | 396 | "Show status information on the script engine.", |
392 | HandleShowStatus); | 397 | HandleShowStatus); |
393 | 398 | ||
394 | MainConsole.Instance.Commands.AddCommand( | 399 | MainConsole.Instance.Commands.AddCommand( |
395 | "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", | 400 | "Scripts", false, "scripts show", "scripts show [<script-item-uuid>+]", "Show script information", |
396 | "Show information on all scripts known to the script engine.\n" | 401 | "Show information on all scripts known to the script engine.\n" |
397 | + "If a <script-item-uuid> is given then only information on that script will be shown.", | 402 | + "If one or more <script-item-uuid>s are given then only information on that script will be shown.", |
398 | HandleShowScripts); | 403 | HandleShowScripts); |
399 | 404 | ||
400 | MainConsole.Instance.Commands.AddCommand( | 405 | MainConsole.Instance.Commands.AddCommand( |
401 | "Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information", | 406 | "Scripts", false, "show scripts", "show scripts [<script-item-uuid>+]", "Show script information", |
402 | "Synonym for scripts show command", HandleShowScripts); | 407 | "Synonym for scripts show command", HandleShowScripts); |
403 | 408 | ||
404 | MainConsole.Instance.Commands.AddCommand( | 409 | MainConsole.Instance.Commands.AddCommand( |
405 | "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", | 410 | "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>+]", "Suspends all running scripts", |
406 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" | 411 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" |
407 | + " script that is currently processing an event.\n" | 412 | + " script that is currently processing an event.\n" |
408 | + "Suspended scripts will continue to accumulate events but won't process them.\n" | 413 | + "Suspended scripts will continue to accumulate events but won't process them.\n" |
409 | + "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", | 414 | + "If one or more <script-item-uuid>s are given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", |
410 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); | 415 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); |
411 | 416 | ||
412 | MainConsole.Instance.Commands.AddCommand( | 417 | MainConsole.Instance.Commands.AddCommand( |
413 | "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", | 418 | "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>+]", "Resumes all suspended scripts", |
414 | "Resumes all currently suspended scripts.\n" | 419 | "Resumes all currently suspended scripts.\n" |
415 | + "Resumed scripts will process all events accumulated whilst suspended.\n" | 420 | + "Resumed scripts will process all events accumulated whilst suspended.\n" |
416 | + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", | 421 | + "If one or more <script-item-uuid>s are given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", |
417 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); | 422 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); |
418 | 423 | ||
419 | MainConsole.Instance.Commands.AddCommand( | 424 | MainConsole.Instance.Commands.AddCommand( |
420 | "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", | 425 | "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>+]", "Stops all running scripts", |
421 | "Stops all running scripts.\n" | 426 | "Stops all running scripts.\n" |
422 | + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", | 427 | + "If one or more <script-item-uuid>s are given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", |
423 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); | 428 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); |
424 | 429 | ||
425 | MainConsole.Instance.Commands.AddCommand( | 430 | MainConsole.Instance.Commands.AddCommand( |
426 | "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", | 431 | "Scripts", false, "scripts start", "scripts start [<script-item-uuid>+]", "Starts all stopped scripts", |
427 | "Starts all stopped scripts.\n" | 432 | "Starts all stopped scripts.\n" |
428 | + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", | 433 | + "If one or more <script-item-uuid>s are given then only that script will be started. Otherwise, all suitable scripts are started.", |
429 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); | 434 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); |
430 | 435 | ||
431 | MainConsole.Instance.Commands.AddCommand( | 436 | MainConsole.Instance.Commands.AddCommand( |
432 | "Scripts", false, "debug script log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script", | 437 | "Scripts", false, "debug scripts log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script", |
433 | "Activates or deactivates extra debug logging for the given script.\n" | 438 | "Activates or deactivates extra debug logging for the given script.\n" |
434 | + "Level == 0, deactivate extra debug logging.\n" | 439 | + "Level == 0, deactivate extra debug logging.\n" |
435 | + "Level >= 1, log state changes.\n" | 440 | + "Level >= 1, log state changes.\n" |
@@ -546,29 +551,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
546 | return; | 551 | return; |
547 | } | 552 | } |
548 | 553 | ||
549 | rawItemId = cmdparams[2]; | 554 | for (int i = 2; i < cmdparams.Length; i++) |
550 | |||
551 | if (!UUID.TryParse(rawItemId, out itemId)) | ||
552 | { | 555 | { |
553 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); | 556 | rawItemId = cmdparams[i]; |
554 | return; | 557 | |
555 | } | 558 | if (!UUID.TryParse(rawItemId, out itemId)) |
556 | |||
557 | if (itemId != UUID.Zero) | ||
558 | { | ||
559 | IScriptInstance instance = GetInstance(itemId); | ||
560 | if (instance == null) | ||
561 | { | 559 | { |
562 | // Commented out for now since this will cause false reports on simulators with more than | 560 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); |
563 | // one scene where the current command line set region is 'root' (which causes commands to | 561 | continue; |
564 | // go to both regions... (sigh) | ||
565 | // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
566 | return; | ||
567 | } | 562 | } |
568 | else | 563 | |
564 | if (itemId != UUID.Zero) | ||
569 | { | 565 | { |
570 | action(instance); | 566 | IScriptInstance instance = GetInstance(itemId); |
571 | return; | 567 | if (instance == null) |
568 | { | ||
569 | // Commented out for now since this will cause false reports on simulators with more than | ||
570 | // one scene where the current command line set region is 'root' (which causes commands to | ||
571 | // go to both regions... (sigh) | ||
572 | // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
573 | continue; | ||
574 | } | ||
575 | else | ||
576 | { | ||
577 | action(instance); | ||
578 | } | ||
572 | } | 579 | } |
573 | } | 580 | } |
574 | } | 581 | } |