aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Console/CommandConsole.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs3
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs99
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs57
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs18
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs27
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs153
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs82
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs126
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs69
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq;
31using System.Text; 30using System.Text;
32 31
32using OMV = OpenMetaverse;
33
33namespace OpenSim.Region.Physics.BulletSPlugin 34namespace OpenSim.Region.Physics.BulletSPlugin
34{ 35{
35public abstract class BSShape 36public 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 @@
1CURRENT PRIORITIES 1CURRENT PRIORITIES
2================================================= 2=================================================
3Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) 3Avatars walking up stairs (HALF DONE)
4Meshes rendering as bounding boxes
5llMoveToTarget
6Vehicle movement on terrain smoothness 4Vehicle movement on terrain smoothness
7limitMotorUp calibration (more down?) 5limitMotorUp calibration (more down?)
8Preferred orientatino angular correction fix 6Preferred orientation angular correction fix
9Surfboard go wonky when turning 7Surfboard 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?
11Boats float low in the water 9Boats float low in the water
@@ -90,6 +88,8 @@ setForce should set a constant force. Different than AddImpulse.
90Implement raycast. 88Implement raycast.
91Implement ShapeCollection.Dispose() 89Implement ShapeCollection.Dispose()
92Implement water as a plain so raycasting and collisions can happen with same. 90Implement water as a plain so raycasting and collisions can happen with same.
91Add collision penetration return
92 Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance()
93Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE 93Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
94 Also osGetPhysicsEngineVerion() maybe. 94 Also osGetPhysicsEngineVerion() maybe.
95Linkset.Position and Linkset.Orientation requre rewrite to properly return 95Linkset.Position and Linkset.Orientation requre rewrite to properly return
@@ -135,6 +135,9 @@ Eliminate collisions between objects in a linkset. (LinksetConstraint)
135 135
136MORE 136MORE
137====================================================== 137======================================================
138Use the HACD convex hull routine in Bullet rather than the C# version.
139Do we need to do convex hulls all the time? Can complex meshes be left meshes?
140 There is some problem with meshes and collisions
138Test avatar walking up stairs. How does compare with SL. 141Test 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.
140Debounce avatar contact so legs don't keep folding up when standing. 143Debounce 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)
275Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE) 278Avatar 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)
280Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE)
281 (Resolution: added BSAPITemplate and then interfaces for C++ Bullet and C# BulletXNA
282Meshes rendering as bounding boxes (DONE)
283 (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box)
284llMoveToTarget (Resolution: added simple motor to update the position.)
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
28using System;
29using System.Collections.Generic;
30using OpenSim.Framework;
31using OpenSim.Framework.Console;
32using OpenSim.Region.ScriptEngine.Interfaces;
33using OpenSim.Region.ScriptEngine.Shared.Api;
34using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
35
36namespace 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 }