Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
	OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
avinationmerge
Melanie 2013-01-10 01:38:03 +00:00
commit 3a495ccd56
21 changed files with 561 additions and 160 deletions

View File

@ -110,10 +110,11 @@ namespace OpenSim.Framework.Console
// Remove initial help keyword
helpParts.RemoveAt(0);
help.Add(""); // Will become a newline.
// General help
if (helpParts.Count == 0)
{
help.Add(""); // Will become a newline.
help.Add(GeneralHelpText);
help.AddRange(CollectAllCommandsHelp());
}
@ -129,6 +130,8 @@ namespace OpenSim.Framework.Console
help.AddRange(CollectHelp(helpParts));
}
help.Add(""); // Will become a newline.
return help;
}
@ -199,14 +202,11 @@ namespace OpenSim.Framework.Console
string descriptiveHelp = commandInfo.descriptive_help;
// If we do have some descriptive help then insert a spacing line before and after for readability.
// If we do have some descriptive help then insert a spacing line before for readability.
if (descriptiveHelp != string.Empty)
help.Add(string.Empty);
help.Add(commandInfo.descriptive_help);
if (descriptiveHelp != string.Empty)
help.Add(string.Empty);
}
else
{

View File

@ -105,7 +105,6 @@ namespace OpenSim.Region.ClientStack.Linden
private static readonly string m_ResourceCostSelectedPath = "0103/";
private static readonly string m_UpdateAgentInformationPath = "0500/";
// These are callbacks which will be setup by the scene so that we can update scene data when we
// receive capability calls
public NewInventoryItem AddNewInventoryItem = null;

View File

@ -322,6 +322,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (asset != null)
{
// Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars
asset.ID = asset.FullID.ToString();
asset.Temporary = false;
asset.Local = false;
m_scene.AssetService.Store(asset);

View File

@ -6,7 +6,7 @@
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyrightD
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the

View File

@ -58,8 +58,6 @@ public sealed class BSCharacter : BSPhysObject
private bool _flying;
private bool _setAlwaysRun;
private bool _throttleUpdates;
private bool _isColliding;
private bool _collidingObj;
private bool _floatOnWater;
private OMV.Vector3 _rotationalVelocity;
private bool _kinematic;
@ -186,10 +184,6 @@ public sealed class BSCharacter : BSPhysObject
// standing as well as moving. Destruction of the avatar will destroy the pre-step action.
private void SetupMovementMotor()
{
// Someday, use a PID motor for asymmetric speed up and slow down
// _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
// Infinite decay and timescale values so motor only changes current to target values.
_velocityMotor = new BSVMotor("BSCharacter.Velocity",
0.2f, // time scale
@ -216,25 +210,68 @@ public sealed class BSCharacter : BSPhysObject
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
/*
// If moveForce is very small, zero things so we don't keep sending microscopic updates to the user
float moveForceMagnitudeSquared = moveForce.LengthSquared();
if (moveForceMagnitudeSquared < 0.0001)
{
DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}",
LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce);
ForceVelocity = OMV.Vector3.Zero;
}
else
{
AddForce(moveForce, false, true);
}
*/
// DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
// Should we check for move force being small and forcing velocity to zero?
// Add special movement force to allow avatars to walk up stepped surfaces.
moveForce += WalkUpStairs();
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
});
}
// Decide of the character is colliding with a low object and compute a force to pop the
// avatar up so it has a chance of walking up and over the low object.
private OMV.Vector3 WalkUpStairs()
{
OMV.Vector3 ret = OMV.Vector3.Zero;
// This test is done if moving forward, not flying and is colliding with something.
// DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
// LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */)
{
// The range near the character's feet where we will consider stairs
float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f;
float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;
// Look for a collision point that is near the character's feet and is oriented the same as the charactor is
foreach (KeyValuePair<uint, ContactPoint> kvp in CollisionsLastTick.m_objCollisionList)
{
// Don't care about collisions with the terrain
if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID)
{
OMV.Vector3 touchPosition = kvp.Value.Position;
// DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
// LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
{
// This contact is within the 'near the feet' range.
// The normal should be our contact point to the object so it is pointing away
// thus the difference between our facing orientation and the normal should be small.
OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation;
OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
if (diff < BSParam.AvatarStepApproachFactor)
{
// Found the stairs contact point. Push up a little to raise the character.
float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor;
ret = new OMV.Vector3(0f, 0f, upForce);
// Also move the avatar up for the new height
OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
ForcePosition = RawPosition + displacement;
}
DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
}
}
}
}
return ret;
}
public override void RequestPhysicsterseUpdate()
{
base.RequestPhysicsterseUpdate();
@ -344,13 +381,11 @@ public sealed class BSCharacter : BSPhysObject
}
set {
_position = value;
PositionSanityCheck();
PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
{
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
if (PhysBody.HasPhysicalBody)
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
ForcePosition = _position;
});
}
}
@ -361,8 +396,11 @@ public sealed class BSCharacter : BSPhysObject
}
set {
_position = value;
PositionSanityCheck();
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
if (PhysBody.HasPhysicalBody)
{
PositionSanityCheck();
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}
}
}
@ -375,7 +413,7 @@ public sealed class BSCharacter : BSPhysObject
bool ret = false;
// TODO: check for out of bounds
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
{
// The character is out of the known/simulated area.
// Upper levels of code will handle the transition to other areas so, for
@ -384,7 +422,7 @@ public sealed class BSCharacter : BSPhysObject
}
// If below the ground, move the avatar up
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
if (Position.Z < terrainHeight)
{
DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
@ -487,6 +525,11 @@ public sealed class BSCharacter : BSPhysObject
});
}
}
public override OMV.Vector3 RawVelocity
{
get { return _velocity; }
set { _velocity = value; }
}
// Directly setting velocity means this is what the user really wants now.
public override OMV.Vector3 Velocity {
get { return _velocity; }

View File

@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; }
}
#region Vehicle parameter setting
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
{
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
@ -546,6 +547,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
}
#endregion // Vehicle parameter setting
// Some of the properties of this prim may have changed.
// Do any updating needed for a vehicle
@ -854,6 +856,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// The movement computed in the linear motor is relative to the vehicle
// coordinates. Rotate the movement to world coordinates.
linearMotorContribution *= VehicleOrientation;
// All the contributions after this are world relative (mostly Z modifications)
// ==================================================================
// Buoyancy: force to overcome gravity.
@ -925,7 +928,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// TODO: Consider taking the rotated size of the object or possibly casting a ray.
if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
{
// TODO: correct position by applying force rather than forcing position.
// Force position because applying force won't get the vehicle through the terrain
Vector3 newPosition = VehiclePosition;
newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
VehiclePosition = newPosition;
@ -980,14 +983,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
float verticalCorrectionVelocity = verticalError / m_VhoverTimescale;
// TODO: implement m_VhoverEfficiency correctly
if (Math.Abs(verticalError) > m_VhoverEfficiency)
{
ret = new Vector3(0f, 0f, verticalCorrectionVelocity);
}
ret = new Vector3(0f, 0f, verticalCorrectionVelocity);
}
VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}",
Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight);
VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}",
Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret);
}
return ret;
@ -1109,6 +1109,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
+ deflectionContribution
+ bankingContribution;
// Add of the above computation are made relative to vehicle coordinates.
// Convert to world coordinates.
m_lastAngularVelocity *= VehicleOrientation;
// ==================================================================
// Apply the correction velocity.
// TODO: Should this be applied as an angular force (torque)?
@ -1220,19 +1224,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin
public Vector3 ComputeAngularDeflection()
{
Vector3 ret = Vector3.Zero;
return ret; // DEBUG DEBUG DEBUG
// Disable angular deflection for the moment.
// Since angularMotorUp and angularDeflection are computed independently, they will calculate
// approximately the same X or Y correction. When added together (when contributions are combined)
// this creates an over-correction and then wabbling as the target is overshot.
// TODO: rethink how the different correction computations inter-relate.
if (m_angularDeflectionEfficiency != 0)
if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero)
{
// The direction the vehicle is moving
Vector3 movingDirection = VehicleVelocity;
movingDirection.Normalize();
// If the vehicle is going backward, it is still pointing forward
movingDirection *= Math.Sign(VehicleForwardSpeed);
// The direction the vehicle is pointing
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
pointingDirection.Normalize();
@ -1241,6 +1247,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
Vector3 deflectionError = movingDirection - pointingDirection;
// Don't try to correct very large errors (not our job)
// if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X);
// if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = PIOverTwo * Math.Sign(deflectionError.Y);
// if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = PIOverTwo * Math.Sign(deflectionError.Z);
if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f;
if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f;
if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f;
@ -1296,33 +1305,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{
// This works by rotating a unit vector to the orientation of the vehicle. The
// roll (tilt) will be Y component of a tilting Z vector (zero for no tilt
// up to one for full over).
// Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
// As the vehicle rolls to the right or left, the Y value will increase from
// zero (straight up) to 1 or -1 (full tilt right or left)
Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation;
// Figure out the yaw value for this much roll.
float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency;
// Keep the sign
if (rollComponents.Y < 0f)
turnComponent = -turnComponent;
// TODO: there must be a better computation of the banking force.
float bankingTurnForce = turnComponent;
// Squared because that seems to give a good value
float yawAngle = (float)Math.Asin(rollComponents.Y * rollComponents.Y) * m_bankingEfficiency;
// actual error = static turn error + dynamic turn error
float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed;
float mixedYawAngle = yawAngle * (1f - m_bankingMix) + yawAngle * m_bankingMix * VehicleForwardSpeed;
// TODO: the banking effect should not go to infinity but what to limit it to?
mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f);
mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f);
// Build the force vector to change rotation from what it is to what it should be
ret.Z = -mixedBankingError;
ret.Z = -mixedYawAngle;
// Don't do it all at once.
ret /= m_bankingTimescale;
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}",
Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret);
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, ret);
}
return ret;
}

View File

@ -75,6 +75,9 @@ public static class BSParam
public static float AvatarCapsuleDepth { get; private set; }
public static float AvatarCapsuleHeight { get; private set; }
public static float AvatarContactProcessingThreshold { get; private set; }
public static float AvatarStepHeight { get; private set; }
public static float AvatarStepApproachFactor { get; private set; }
public static float AvatarStepForceFactor { get; private set; }
public static float VehicleAngularDamping { get; private set; }
@ -403,6 +406,21 @@ public static class BSParam
(s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return AvatarContactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ),
new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction",
0.3f,
(s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); },
(s) => { return AvatarStepHeight; },
(s,p,l,v) => { AvatarStepHeight = v; } ),
new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)",
0.6f,
(s,cf,p,v) => { AvatarStepApproachFactor = cf.GetFloat(p, v); },
(s) => { return AvatarStepApproachFactor; },
(s,p,l,v) => { AvatarStepApproachFactor = v; } ),
new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step",
2.0f,
(s,cf,p,v) => { AvatarStepForceFactor = cf.GetFloat(p, v); },
(s) => { return AvatarStepForceFactor; },
(s,p,l,v) => { AvatarStepForceFactor = v; } ),
new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
0.95f,

View File

@ -79,6 +79,7 @@ public abstract class BSPhysObject : PhysicsActor
Material = MaterialAttributes.Material.Wood;
CollisionCollection = new CollisionEventUpdate();
CollisionsLastTick = CollisionCollection;
SubscribedEventsMs = 0;
CollidingStep = 0;
CollidingGroundStep = 0;
@ -159,6 +160,7 @@ public abstract class BSPhysObject : PhysicsActor
public abstract OMV.Quaternion ForceOrientation { get; set; }
// The system is telling us the velocity it wants to move at.
// Velocity in world coordinates.
// protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor
public override OMV.Vector3 TargetVelocity
{
@ -169,6 +171,15 @@ public abstract class BSPhysObject : PhysicsActor
Velocity = value;
}
}
public virtual float TargetSpeed
{
get
{
OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation));
return characterOrientedVelocity.X;
}
}
public abstract OMV.Vector3 RawVelocity { get; set; }
public abstract OMV.Vector3 ForceVelocity { get; set; }
public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
@ -177,6 +188,15 @@ public abstract class BSPhysObject : PhysicsActor
public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
public virtual float ForwardSpeed
{
get
{
OMV.Vector3 characterOrientedVelocity = RawVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation));
return characterOrientedVelocity.X;
}
}
#region Collisions
// Requested number of milliseconds between collision events. Zero means disabled.
@ -223,9 +243,13 @@ public abstract class BSPhysObject : PhysicsActor
// The collisions that have been collected this tick
protected CollisionEventUpdate CollisionCollection;
// Remember collisions from last tick for fancy collision based actions
// (like a BSCharacter walking up stairs).
protected CollisionEventUpdate CollisionsLastTick;
// The simulation step is telling this object about a collision.
// Return 'true' if a collision was processed and should be sent up.
// Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
// Called at taint time from within the Step() function
public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
@ -286,6 +310,9 @@ public abstract class BSPhysObject : PhysicsActor
// DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
base.SendCollisionUpdate(CollisionCollection);
// Remember the collisions from this tick for some collision specific processing.
CollisionsLastTick = CollisionCollection;
// The CollisionCollection instance is passed around in the simulator.
// Make sure we don't have a handle to that one and that a new one is used for next time.
// This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,

View File

@ -562,7 +562,7 @@ public sealed class BSPrim : BSPhysObject
}
return;
}
public OMV.Vector3 RawVelocity
public override OMV.Vector3 RawVelocity
{
get { return _velocity; }
set { _velocity = value; }

View File

@ -27,24 +27,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OMV = OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public abstract class BSShape
{
public IntPtr ptr { get; set; }
public BSPhysicsShapeType type { get; set; }
public System.UInt64 key { get; set; }
public int referenceCount { get; set; }
public DateTime lastReferenced { get; set; }
public BSShape()
{
ptr = IntPtr.Zero;
type = BSPhysicsShapeType.SHAPE_UNKNOWN;
key = 0;
referenceCount = 0;
lastReferenced = DateTime.Now;
}
@ -63,7 +58,7 @@ public abstract class BSShape
}
// Compound shapes are handled special as they are rebuilt from scratch.
// This isn't too great a hardship since most of the child shapes will already been created.
// This isn't too great a hardship since most of the child shapes will have already been created.
if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
{
// 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
physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
}
// Avatars have their own unique shape
if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR)
{
// Getting a reference to a compound shape gets you the compound shape with the root prim shape added
ret = BSShapeAvatar.GetReference(prim);
physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret);
}
if (ret == null)
ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
@ -92,9 +95,9 @@ public abstract class BSShape
// protected abstract static BSShape GetReference();
// Returns a string for debugging that uniquily identifies the memory used by this instance
public string AddrString
public virtual string AddrString
{
get { return ptr.ToString("X"); }
get { return "unknown"; }
}
public override string ToString()
@ -102,10 +105,6 @@ public abstract class BSShape
StringBuilder buff = new StringBuilder();
buff.Append("<p=");
buff.Append(AddrString);
buff.Append(",s=");
buff.Append(type.ToString());
buff.Append(",k=");
buff.Append(key.ToString("X"));
buff.Append(",c=");
buff.Append(referenceCount.ToString());
buff.Append(">");
@ -228,5 +227,131 @@ public class BSShapeAvatar : BSShape
return new BSShapeNull();
}
public override void Dereference(BSScene physicsScene) { }
// From the front:
// A---A
// / \
// B-------B
// / \ +Z
// C-----------C |
// \ / -Y --+-- +Y
// \ / |
// \ / -Z
// D-----D
// \ /
// E-E
// From the top A and E are just lines.
// B, C and D are hexagons:
//
// C1--C2 +X
// / \ |
// C0 C3 -Y --+-- +Y
// \ / |
// C5--C4 -X
// Zero goes directly through the middle so the offsets are from that middle axis
// and up and down from a middle horizon (A and E are the same distance from the zero).
// The height, width and depth is one. All scaling is done by the simulator.
// Z component -- how far the level is from the middle zero
private const float Aup = 0.5f;
private const float Bup = 0.4f;
private const float Cup = 0.3f;
private const float Dup = -0.4f;
private const float Eup = -0.5f;
// Y component -- distance from center to x0 and x3
private const float Awid = 0.25f;
private const float Bwid = 0.3f;
private const float Cwid = 0.5f;
private const float Dwid = 0.3f;
private const float Ewid = 0.2f;
// Y component -- distance from center to x1, x2, x4 and x5
private const float Afwid = 0.0f;
private const float Bfwid = 0.2f;
private const float Cfwid = 0.4f;
private const float Dfwid = 0.2f;
private const float Efwid = 0.0f;
// X component -- distance from zero to the front or back of a level
private const float Adep = 0f;
private const float Bdep = 0.3f;
private const float Cdep = 0.5f;
private const float Ddep = 0.2f;
private const float Edep = 0f;
private OMV.Vector3[] avatarVertices = {
new OMV.Vector3( 0.0f, -Awid, Aup), // A0
new OMV.Vector3( 0.0f, +Awid, Aup), // A3
new OMV.Vector3( 0.0f, -Bwid, Bup), // B0
new OMV.Vector3(+Bdep, -Bfwid, Bup), // B1
new OMV.Vector3(+Bdep, +Bfwid, Bup), // B2
new OMV.Vector3( 0.0f, +Bwid, Bup), // B3
new OMV.Vector3(-Bdep, +Bfwid, Bup), // B4
new OMV.Vector3(-Bdep, -Bfwid, Bup), // B5
new OMV.Vector3( 0.0f, -Cwid, Cup), // C0
new OMV.Vector3(+Cdep, -Cfwid, Cup), // C1
new OMV.Vector3(+Cdep, +Cfwid, Cup), // C2
new OMV.Vector3( 0.0f, +Cwid, Cup), // C3
new OMV.Vector3(-Cdep, +Cfwid, Cup), // C4
new OMV.Vector3(-Cdep, -Cfwid, Cup), // C5
new OMV.Vector3( 0.0f, -Dwid, Dup), // D0
new OMV.Vector3(+Ddep, -Dfwid, Dup), // D1
new OMV.Vector3(+Ddep, +Dfwid, Dup), // D2
new OMV.Vector3( 0.0f, +Dwid, Dup), // D3
new OMV.Vector3(-Ddep, +Dfwid, Dup), // D4
new OMV.Vector3(-Ddep, -Dfwid, Dup), // D5
new OMV.Vector3( 0.0f, -Ewid, Eup), // E0
new OMV.Vector3( 0.0f, +Ewid, Eup), // E3
};
// Offsets of the vertices in the vertices array
private enum Ind : int
{
A0, A3,
B0, B1, B2, B3, B4, B5,
C0, C1, C2, C3, C4, C5,
D0, D1, D2, D3, D4, D5,
E0, E3
}
// Comments specify trianges and quads in clockwise direction
private Ind[] avatarIndices = {
Ind.A0, Ind.B0, Ind.B1, // A0,B0,B1
Ind.A0, Ind.B1, Ind.B2, Ind.B2, Ind.A3, Ind.A0, // A0,B1,B2,A3
Ind.A3, Ind.B2, Ind.B3, // A3,B2,B3
Ind.A3, Ind.B3, Ind.B4, // A3,B3,B4
Ind.A3, Ind.B4, Ind.B5, Ind.B5, Ind.A0, Ind.A3, // A3,B4,B5,A0
Ind.A0, Ind.B5, Ind.B0, // A0,B5,B0
Ind.B0, Ind.C0, Ind.C1, Ind.C1, Ind.B1, Ind.B0, // B0,C0,C1,B1
Ind.B1, Ind.C1, Ind.C2, Ind.C2, Ind.B2, Ind.B1, // B1,C1,C2,B2
Ind.B2, Ind.C2, Ind.C3, Ind.C3, Ind.B3, Ind.B2, // B2,C2,C3,B3
Ind.B3, Ind.C3, Ind.C4, Ind.C4, Ind.B4, Ind.B3, // B3,C3,C4,B4
Ind.B4, Ind.C4, Ind.C5, Ind.C5, Ind.B5, Ind.B4, // B4,C4,C5,B5
Ind.B5, Ind.C5, Ind.C0, Ind.C0, Ind.B0, Ind.B5, // B5,C5,C0,B0
Ind.C0, Ind.D0, Ind.D1, Ind.D1, Ind.C1, Ind.C0, // C0,D0,D1,C1
Ind.C1, Ind.D1, Ind.D2, Ind.D2, Ind.C2, Ind.C1, // C1,D1,D2,C2
Ind.C2, Ind.D2, Ind.D3, Ind.D3, Ind.C3, Ind.C2, // C2,D2,D3,C3
Ind.C3, Ind.D3, Ind.D4, Ind.D4, Ind.C4, Ind.C3, // C3,D3,D4,C4
Ind.C4, Ind.D4, Ind.D5, Ind.D5, Ind.C5, Ind.C4, // C4,D4,D5,C5
Ind.C5, Ind.D5, Ind.D0, Ind.D0, Ind.C0, Ind.C5, // C5,D5,D0,C0
Ind.E0, Ind.D0, Ind.D1, // E0,D0,D1
Ind.E0, Ind.D1, Ind.D2, Ind.D2, Ind.E3, Ind.E0, // E0,D1,D2,E3
Ind.E3, Ind.D2, Ind.D3, // E3,D2,D3
Ind.E3, Ind.D3, Ind.D4, // E3,D3,D4
Ind.E3, Ind.D4, Ind.D5, Ind.D5, Ind.E0, Ind.E3, // E3,D4,D5,E0
Ind.E0, Ind.D5, Ind.D0, // E0,D5,D0
};
}
}

View File

@ -142,6 +142,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody);
// Frees both the body and the shape.
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody);
m_terrainBody.Clear();
m_terrainShape.Clear();
}
}

View File

@ -114,8 +114,10 @@ public class BulletShape
public virtual void Clear() { }
public virtual bool HasPhysicalShape { get { return false; } }
// Make another reference to this physical object.
public virtual BulletShape Clone() { return new BulletShape(); }
// Return 'true' if this and other refer to the same physical object
public virtual bool ReferenceSame(BulletShape xx) { return false; }

View File

@ -1,11 +1,9 @@
CURRENT PRIORITIES
=================================================
Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE)
Meshes rendering as bounding boxes
llMoveToTarget
Avatars walking up stairs (HALF DONE)
Vehicle movement on terrain smoothness
limitMotorUp calibration (more down?)
Preferred orientatino angular correction fix
Preferred orientation angular correction fix
Surfboard go wonky when turning
Angular motor direction is global coordinates rather than local coordinates?
Boats float low in the water
@ -90,6 +88,8 @@ setForce should set a constant force. Different than AddImpulse.
Implement raycast.
Implement ShapeCollection.Dispose()
Implement water as a plain so raycasting and collisions can happen with same.
Add collision penetration return
Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance()
Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
Also osGetPhysicsEngineVerion() maybe.
Linkset.Position and Linkset.Orientation requre rewrite to properly return
@ -135,6 +135,9 @@ Eliminate collisions between objects in a linkset. (LinksetConstraint)
MORE
======================================================
Use the HACD convex hull routine in Bullet rather than the C# version.
Do we need to do convex hulls all the time? Can complex meshes be left meshes?
There is some problem with meshes and collisions
Test avatar walking up stairs. How does compare with SL.
Radius of the capsule affects ability to climb edges.
Debounce avatar contact so legs don't keep folding up when standing.
@ -274,3 +277,8 @@ llSetBuoyancy() (DONE)
(Resolution: Bullet resets object gravity when added to world. Moved set gravity)
Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE)
(Resolution: set default density to 3.5 (from 60) which is closer to SL)
Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE)
(Resolution: added BSAPITemplate and then interfaces for C++ Bullet and C# BulletXNA
Meshes rendering as bounding boxes (DONE)
(Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box)
llMoveToTarget (Resolution: added simple motor to update the position.)

View File

@ -42,6 +42,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Used by one-off and repeated sensors
/// </summary>
public class SensorInfo
{
public uint localID;
public UUID itemID;
public double interval;
public DateTime next;
public string name;
public UUID keyID;
public int type;
public double range;
public double arc;
public SceneObjectPart host;
public SensorInfo Clone()
{
return (SensorInfo)this.MemberwiseClone();
}
}
public AsyncCommandManager m_CmdManager;
/// <summary>
@ -77,24 +100,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
private double maximumRange = 96.0;
private int maximumToReturn = 16;
//
// SenseRepeater and Sensors
//
private class SenseRepeatClass
{
public uint localID;
public UUID itemID;
public double interval;
public DateTime next;
public string name;
public UUID keyID;
public int type;
public double range;
public double arc;
public SceneObjectPart host;
}
//
// Sensed entity
//
@ -127,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
///
/// Always lock SenseRepeatListLock when updating this list.
/// </remarks>
private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
private List<SensorInfo> SenseRepeaters = new List<SensorInfo>();
private object SenseRepeatListLock = new object();
public void SetSenseRepeatEvent(uint m_localID, UUID m_itemID,
@ -141,7 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
return;
// Add to timer
SenseRepeatClass ts = new SenseRepeatClass();
SensorInfo ts = new SensorInfo();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = sec;
@ -160,11 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
AddSenseRepeater(ts);
}
private void AddSenseRepeater(SenseRepeatClass senseRepeater)
private void AddSenseRepeater(SensorInfo senseRepeater)
{
lock (SenseRepeatListLock)
{
List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>(SenseRepeaters);
List<SensorInfo> newSenseRepeaters = new List<SensorInfo>(SenseRepeaters);
newSenseRepeaters.Add(senseRepeater);
SenseRepeaters = newSenseRepeaters;
}
@ -175,8 +180,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
// Remove from timer
lock (SenseRepeatListLock)
{
List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>();
foreach (SenseRepeatClass ts in SenseRepeaters)
List<SensorInfo> newSenseRepeaters = new List<SensorInfo>();
foreach (SensorInfo ts in SenseRepeaters)
{
if (ts.localID != m_localID || ts.itemID != m_itemID)
{
@ -191,7 +196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
public void CheckSenseRepeaterEvents()
{
// Go through all timers
foreach (SenseRepeatClass ts in SenseRepeaters)
foreach (SensorInfo ts in SenseRepeaters)
{
// Time has passed?
if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
@ -208,7 +213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
double range, double arc, SceneObjectPart host)
{
// Add to timer
SenseRepeatClass ts = new SenseRepeatClass();
SensorInfo ts = new SensorInfo();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = 0;
@ -224,7 +229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
SensorSweep(ts);
}
private void SensorSweep(SenseRepeatClass ts)
private void SensorSweep(SensorInfo ts)
{
if (ts.host == null)
{
@ -300,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
}
}
private List<SensedEntity> doObjectSensor(SenseRepeatClass ts)
private List<SensedEntity> doObjectSensor(SensorInfo ts)
{
List<EntityBase> Entities;
List<SensedEntity> sensedEntities = new List<SensedEntity>();
@ -451,7 +456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
return sensedEntities;
}
private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
private List<SensedEntity> doAgentSensor(SensorInfo ts)
{
List<SensedEntity> sensedEntities = new List<SensedEntity>();
@ -630,7 +635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
List<Object> data = new List<Object>();
foreach (SenseRepeatClass ts in SenseRepeaters)
foreach (SensorInfo ts in SenseRepeaters)
{
if (ts.itemID == itemID)
{
@ -660,7 +665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
while (idx < data.Length)
{
SenseRepeatClass ts = new SenseRepeatClass();
SensorInfo ts = new SensorInfo();
ts.localID = localID;
ts.itemID = itemID;
@ -681,5 +686,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
idx += 6;
}
}
public List<SensorInfo> GetSensorInfo()
{
List<SensorInfo> retList = new List<SensorInfo>();
lock (SenseRepeatListLock)
{
foreach (SensorInfo i in SenseRepeaters)
retList.Add(i.Clone());
}
return retList;
}
}
}
}

View File

@ -35,6 +35,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class Timer
{
public class TimerInfo
{
public uint localID;
public UUID itemID;
//public double interval;
public long interval;
//public DateTime next;
public long next;
public TimerInfo Clone()
{
return (TimerInfo)this.MemberwiseClone();
}
}
public AsyncCommandManager m_CmdManager;
public int TimersCount
@ -59,17 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
return localID.ToString() + itemID.ToString();
}
private class TimerClass
{
public uint localID;
public UUID itemID;
//public double interval;
public long interval;
//public DateTime next;
public long next;
}
private Dictionary<string,TimerClass> Timers = new Dictionary<string,TimerClass>();
private Dictionary<string,TimerInfo> Timers = new Dictionary<string,TimerInfo>();
private object TimerListLock = new object();
public void SetTimerEvent(uint m_localID, UUID m_itemID, double sec)
@ -81,7 +86,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
}
// Add to timer
TimerClass ts = new TimerClass();
TimerInfo ts = new TimerInfo();
ts.localID = m_localID;
ts.itemID = m_itemID;
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
if (Timers.Count == 0)
return;
Dictionary<string, TimerClass>.ValueCollection tvals;
Dictionary<string, TimerInfo>.ValueCollection tvals;
lock (TimerListLock)
{
// Go through all timers
tvals = Timers.Values;
}
foreach (TimerClass ts in tvals)
foreach (TimerInfo ts in tvals)
{
// Time has passed?
if (ts.next < DateTime.Now.Ticks)
@ -149,8 +154,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
lock (TimerListLock)
{
Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values;
foreach (TimerClass ts in tvals)
Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values;
foreach (TimerInfo ts in tvals)
{
if (ts.itemID == itemID)
{
@ -169,7 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
while (idx < data.Length)
{
TimerClass ts = new TimerClass();
TimerInfo ts = new TimerInfo();
ts.localID = localID;
ts.itemID = itemID;
@ -183,5 +188,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
}
}
}
public List<TimerInfo> GetTimersInfo()
{
List<TimerInfo> retList = new List<TimerInfo>();
lock (TimerListLock)
{
foreach (TimerInfo i in Timers.Values)
retList.Add(i.Clone());
}
return retList;
}
}
}

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared.Api;
using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
namespace OpenSim.Region.ScriptEngine.XEngine
{
public class ScriptEngineConsoleCommands
{
IScriptEngine m_engine;
public ScriptEngineConsoleCommands(IScriptEngine engine)
{
m_engine = engine;
}
public void RegisterCommands()
{
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "show script sensors", "show script sensors", "Show script sensors information",
HandleShowSensors);
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "show script timers", "show script timers", "Show script sensors information",
HandleShowTimers);
}
private bool IsSceneSelected()
{
return MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World;
}
private void HandleShowSensors(string module, string[] cmdparams)
{
if (!IsSceneSelected())
return;
SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(m_engine);
if (sr == null)
{
MainConsole.Instance.Output("Plugin not yet initialized");
return;
}
List<SensorRepeat.SensorInfo> sensorInfo = sr.GetSensorInfo();
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Part name", 40);
cdt.AddColumn("Script item ID", 36);
cdt.AddColumn("Type", 4);
cdt.AddColumn("Interval", 8);
cdt.AddColumn("Range", 8);
cdt.AddColumn("Arc", 8);
foreach (SensorRepeat.SensorInfo s in sensorInfo)
{
cdt.AddRow(s.host.Name, s.itemID, s.type, s.interval, s.range, s.arc);
}
MainConsole.Instance.Output(cdt.ToString());
MainConsole.Instance.OutputFormat("Total: {0}", sensorInfo.Count);
}
private void HandleShowTimers(string module, string[] cmdparams)
{
if (!IsSceneSelected())
return;
Timer timerPlugin = AsyncCommandManager.GetTimerPlugin(m_engine);
if (timerPlugin == null)
{
MainConsole.Instance.Output("Plugin not yet initialized");
return;
}
List<Timer.TimerInfo> timersInfo = timerPlugin.GetTimersInfo();
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Part local ID", 13);
cdt.AddColumn("Script item ID", 36);
cdt.AddColumn("Interval", 10);
cdt.AddColumn("Next", 8);
foreach (Timer.TimerInfo t in timersInfo)
{
// Convert from 100 ns ticks back to seconds
cdt.AddRow(t.localID, t.itemID, (double)t.interval / 10000000, t.next);
}
MainConsole.Instance.Output(cdt.ToString());
MainConsole.Instance.OutputFormat("Total: {0}", timersInfo.Count);
}
}
}

View File

@ -237,6 +237,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
}
}
private ScriptEngineConsoleCommands m_consoleCommands;
public string ScriptEngineName
{
get { return "XEngine"; }
@ -386,50 +388,53 @@ namespace OpenSim.Region.ScriptEngine.XEngine
OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved;
}
m_consoleCommands = new ScriptEngineConsoleCommands(this);
m_consoleCommands.RegisterCommands();
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "xengine status", "xengine status", "Show status information",
"Show status information on the script engine.",
HandleShowStatus);
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information",
"Scripts", false, "scripts show", "scripts show [<script-item-uuid>+]", "Show script information",
"Show information on all scripts known to the script engine.\n"
+ "If a <script-item-uuid> is given then only information on that script will be shown.",
+ "If one or more <script-item-uuid>s are given then only information on that script will be shown.",
HandleShowScripts);
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information",
"Scripts", false, "show scripts", "show scripts [<script-item-uuid>+]", "Show script information",
"Synonym for scripts show command", HandleShowScripts);
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts",
"Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>+]", "Suspends all running scripts",
"Suspends all currently running scripts. This only suspends event delivery, it will not suspend a"
+ " script that is currently processing an event.\n"
+ "Suspended scripts will continue to accumulate events but won't process them.\n"
+ "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.",
+ "If one or more <script-item-uuid>s are given then only that script will be suspended. Otherwise, all suitable scripts are suspended.",
(module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript));
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts",
"Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>+]", "Resumes all suspended scripts",
"Resumes all currently suspended scripts.\n"
+ "Resumed scripts will process all events accumulated whilst suspended.\n"
+ "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
+ "If one or more <script-item-uuid>s are given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
(module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript));
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts",
"Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>+]", "Stops all running scripts",
"Stops all running scripts.\n"
+ "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
+ "If one or more <script-item-uuid>s are given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
(module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript));
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts",
"Scripts", false, "scripts start", "scripts start [<script-item-uuid>+]", "Starts all stopped scripts",
"Starts all stopped scripts.\n"
+ "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.",
+ "If one or more <script-item-uuid>s are given then only that script will be started. Otherwise, all suitable scripts are started.",
(module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
MainConsole.Instance.Commands.AddCommand(
"Scripts", false, "debug script log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script",
"Scripts", false, "debug scripts log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script",
"Activates or deactivates extra debug logging for the given script.\n"
+ "Level == 0, deactivate extra debug logging.\n"
+ "Level >= 1, log state changes.\n"
@ -546,29 +551,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
return;
}
rawItemId = cmdparams[2];
if (!UUID.TryParse(rawItemId, out itemId))
for (int i = 2; i < cmdparams.Length; i++)
{
MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId);
return;
}
if (itemId != UUID.Zero)
{
IScriptInstance instance = GetInstance(itemId);
if (instance == null)
rawItemId = cmdparams[i];
if (!UUID.TryParse(rawItemId, out itemId))
{
// Commented out for now since this will cause false reports on simulators with more than
// one scene where the current command line set region is 'root' (which causes commands to
// go to both regions... (sigh)
// MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId);
return;
MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId);
continue;
}
else
if (itemId != UUID.Zero)
{
action(instance);
return;
IScriptInstance instance = GetInstance(itemId);
if (instance == null)
{
// Commented out for now since this will cause false reports on simulators with more than
// one scene where the current command line set region is 'root' (which causes commands to
// go to both regions... (sigh)
// MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId);
continue;
}
else
{
action(instance);
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.