diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index da59eabff1..60b7190c8a 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -301,6 +301,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp UrlData urlData = m_RequestMap[request]; if (!urlData.requests[request].responseSent) { + string responseBody = body; + if (urlData.requests[request].responseType.Equals("text/plain")) + { + string value; + if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) + { + if (value != null && value.IndexOf("MSIE") >= 0) + { + // wrap the html escaped response if the target client is IE + // It ignores "text/plain" if the body is html + responseBody = "" + System.Web.HttpUtility.HtmlEncode(body) + ""; + } + } + } + urlData.requests[request].responseCode = status; urlData.requests[request].responseBody = body; //urlData.requests[request].ev.Set(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0fe98424fc..f0373485a2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4226,6 +4226,7 @@ namespace OpenSim.Region.Framework.Scenes result.distance = distance2; result.HitTF = true; result.ipoint = q; + result.face = i; //m_log.Info("[FACE]:" + i.ToString()); //m_log.Info("[POINT]: " + q.ToString()); //m_log.Info("[DIST]: " + distance2.ToString()); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 49b17305df..f63d83c46f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.InteropServices; using System.Text; using OpenSim.Framework; @@ -130,10 +131,12 @@ private sealed class BulletConstraintXNA : BulletConstraint } } internal int m_maxCollisions; - internal CollisionDesc[] m_collisionArray; - + internal CollisionDesc[] UpdatedCollisions; + internal int LastCollisionDesc = 0; internal int m_maxUpdatesPerFrame; - internal EntityProperties[] m_updateArray; + internal int LastEntityProperty = 0; + + internal EntityProperties[] UpdatedObjects; private static int m_collisionsThisFrame; private BSScene PhysicsScene { get; set; } @@ -900,7 +903,7 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape shape1 = (pShape as BulletShapeXNA).shape; // TODO: Turn this from a reference copy to a Value Copy. - BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSPhysicsShapeType.SHAPE_UNKNOWN); + BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSShapeTypeFromBroadPhaseNativeType(shape1.GetShapeType())); return shape2; } @@ -922,9 +925,9 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape shape = (pShape as BulletShapeXNA).shape; //UpdateSingleAabb(world, shape); // TODO: Feed Update array into null - SimMotionState motionState = new SimMotionState(world, pLocalID, mat, null); + SimMotionState motionState = new SimMotionState(this, pLocalID, mat, null); RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero); - RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, new SimMotionState(world, pLocalID, mat, null),shape,IndexedVector3.Zero) + RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, motionState, shape, IndexedVector3.Zero) { m_mass = 0 }; @@ -1039,8 +1042,8 @@ private sealed class BulletConstraintXNA : BulletConstraint ) { - m_updateArray = updateArray; - m_collisionArray = collisionArray; + UpdatedObjects = updateArray; + UpdatedCollisions = collisionArray; /* TODO */ ConfigurationParameters[] configparms = new ConfigurationParameters[1]; configparms[0] = parms; @@ -1135,10 +1138,7 @@ private sealed class BulletConstraintXNA : BulletConstraint SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); - - - world.UpdatedObjects = BSAPIXNA.GetBulletXNAEntityStruct(BSAPIXNA.BulletSimEntityStructToByteArray(updateArray, updateArray.Length)); - world.UpdatedCollisions = BSAPIXNA.GetBulletXNACollisionStruct(BSAPIXNA.BulletSimCollisionStructToByteArray(collisionArray, collisionArray.Length)); + world.LastCollisionDesc = 0; world.LastEntityProperty = 0; @@ -1332,7 +1332,7 @@ private sealed class BulletConstraintXNA : BulletConstraint { CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; CollisionShape shape = collisionObject.GetCollisionShape(); - return new BulletShapeXNA(shape,BSPhysicsShapeType.SHAPE_UNKNOWN); + return new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType())); } //(PhysicsScene.World.ptr, nativeShapeData) @@ -1395,10 +1395,148 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape ret = null; ret = compoundshape.GetChildShape(pii); compoundshape.RemoveChildShapeByIndex(pii); - return new BulletShapeXNA(ret, BSPhysicsShapeType.SHAPE_UNKNOWN); + return new BulletShapeXNA(ret, BSShapeTypeFromBroadPhaseNativeType(ret.GetShapeType())); + } + + public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { + /* TODO */ + if (cShape == null) + return null; + CompoundShape compoundShape = (cShape as BulletShapeXNA).shape as CompoundShape; + CollisionShape shape = compoundShape.GetChildShape(indx); + BulletShape retShape = new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType())); + + + return null; + } + + public BSPhysicsShapeType BSShapeTypeFromBroadPhaseNativeType(BroadphaseNativeTypes pin) + { + switch (pin) + { + case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_BOX; + break; + case BroadphaseNativeTypes.TRIANGLE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + + case BroadphaseNativeTypes.TETRAHEDRAL_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_HULL; + break; + case BroadphaseNativeTypes.CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CUSTOM_POLYHEDRAL_SHAPE_TYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + //implicit convex shapes + case BroadphaseNativeTypes.IMPLICIT_CONVEX_SHAPES_START_HERE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_SPHERE; + break; + case BroadphaseNativeTypes.MULTI_SPHERE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_CAPSULE; + break; + case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_CONE; + break; + case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_CYLINDER; + break; + case BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.MINKOWSKI_SUM_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.BOX_2D_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CONVEX_2D_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CUSTOM_CONVEX_SHAPE_TYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + //concave shape + case BroadphaseNativeTypes.CONCAVE_SHAPES_START_HERE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + case BroadphaseNativeTypes.TRIANGLE_MESH_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + case BroadphaseNativeTypes.SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + ///used for demo integration FAST/Swift collision library and Bullet + case BroadphaseNativeTypes.FAST_CONCAVE_MESH_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + //terrain + case BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_HEIGHTMAP; + break; + ///Used for GIMPACT Trimesh integration + case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + ///Multimaterial mesh + case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + + case BroadphaseNativeTypes.EMPTY_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_GROUNDPLANE; + break; + case BroadphaseNativeTypes.CUSTOM_CONCAVE_SHAPE_TYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CONCAVE_SHAPES_END_HERE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + + case BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_COMPOUND; + break; + + case BroadphaseNativeTypes.SOFTBODY_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + case BroadphaseNativeTypes.HFFLUID_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.INVALID_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + } + return BSPhysicsShapeType.SHAPE_UNKNOWN; } - public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ } @@ -1636,11 +1774,21 @@ private sealed class BulletConstraintXNA : BulletConstraint return epic; } - private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, + private int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates) { int numSimSteps = 0; + Array.Clear(UpdatedObjects, 0, UpdatedObjects.Length); + Array.Clear(UpdatedCollisions, 0, UpdatedCollisions.Length); + LastEntityProperty=0; + + + + + + LastCollisionDesc=0; + updatedEntityCount = 0; collidersCount = 0; @@ -1651,8 +1799,6 @@ private sealed class BulletConstraintXNA : BulletConstraint world.LastCollisionDesc = 0; world.LastEntityProperty = 0; - world.UpdatedObjects = new BulletXNA.EntityProperties[maxUpdates]; - world.UpdatedCollisions = new BulletXNA.CollisionDesc[maxCollisions]; numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); int updates = 0; @@ -1675,7 +1821,7 @@ private sealed class BulletConstraintXNA : BulletConstraint IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A - RecordCollision(world, objA, objB, contactPoint, contactNormal); + RecordCollision(this, objA, objB, contactPoint, contactNormal,manifoldPoint.GetDistance()); m_collisionsThisFrame ++; if (m_collisionsThisFrame >= 9999999) break; @@ -1683,15 +1829,16 @@ private sealed class BulletConstraintXNA : BulletConstraint } - updatedEntityCount = world.LastEntityProperty; - updatedEntities = GetBulletSimEntityStruct(BulletXNAEntityStructToByteArray(world.UpdatedObjects, world.LastEntityProperty)); + updatedEntityCount = LastEntityProperty; + updatedEntities = UpdatedObjects; + - collidersCount = world.LastCollisionDesc; - colliders = - GetBulletSimCollisionStruct(BulletXNACollisionStructToByteArray(world.UpdatedCollisions, world.LastCollisionDesc));//new List(world.UpdatedCollisions); + collidersCount = LastCollisionDesc; + colliders = UpdatedCollisions; + } else @@ -1699,8 +1846,8 @@ private sealed class BulletConstraintXNA : BulletConstraint //if (updatedEntities is null) //updatedEntities = new List(); //updatedEntityCount = 0; - //if (colliders is null) - //colliders = new List(); + + //collidersCount = 0; updatedEntities = new EntityProperties[0]; @@ -1711,8 +1858,64 @@ private sealed class BulletConstraintXNA : BulletConstraint } return numSimSteps; } + public void RecordGhostCollisions(PairCachingGhostObject obj) + { + /* + *void BulletSim::RecordGhostCollisions(btPairCachingGhostObject* obj) +{ + btManifoldArray manifoldArray; + btBroadphasePairArray& pairArray = obj->getOverlappingPairCache()->getOverlappingPairArray(); + int numPairs = pairArray.size(); - private static void RecordCollision(CollisionWorld world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) + // For all the pairs of sets of contact points + for (int i=0; i < numPairs; i++) + { + if (m_collisionsThisFrame >= m_maxCollisionsPerFrame) + break; + + manifoldArray.clear(); + const btBroadphasePair& pair = pairArray[i]; + + // The real representation is over in the world pair cache + btBroadphasePair* collisionPair = m_worldData.dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1); + if (!collisionPair) + continue; + + if (collisionPair->m_algorithm) + collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + + // The collision pair has sets of collision points (manifolds) + for (int j=0; j < manifoldArray.size(); j++) + { + btPersistentManifold* contactManifold = manifoldArray[j]; + int numContacts = contactManifold->getNumContacts(); + + const btCollisionObject* objA = static_cast(contactManifold->getBody0()); + const btCollisionObject* objB = static_cast(contactManifold->getBody1()); + + // TODO: this is a more thurough check than the regular collision code -- + // here we find the penetrating contact in the manifold but for regular + // collisions we assume the first point in the manifold is good enough. + // Decide of this extra checking is required or if first point is good enough. + for (int p=0; p < numContacts; p++) + { + const btManifoldPoint& pt = contactManifold->getContactPoint(p); + // If a penetrating contact, this is a hit + if (pt.getDistance()<0.f) + { + const btVector3& contactPoint = pt.getPositionWorldOnA(); + const btVector3& normalOnA = -pt.m_normalWorldOnB; + RecordCollision(objA, objB, contactPoint, normalOnA, pt.getDistance()); + // Only one contact point for each set of colliding objects + break; + } + } + } + } +} + */ + } + private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm, float penetration) { IndexedVector3 contactNormal = norm; @@ -1733,12 +1936,14 @@ private sealed class BulletConstraintXNA : BulletConstraint ulong collisionID = ((ulong) idA << 32) | idB; - BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() + CollisionDesc cDesc = new CollisionDesc() { aID = idA, bID = idB, - point = contact, - normal = contactNormal + point = new Vector3(contact.X,contact.Y,contact.Z), + normal = new Vector3(contactNormal.X,contactNormal.Y,contactNormal.Z), + penetration = penetration + }; if (world.LastCollisionDesc < world.UpdatedCollisions.Length) world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); @@ -1764,7 +1969,8 @@ private sealed class BulletConstraintXNA : BulletConstraint return ent; } - public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */ return false; } + public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */ + return false; } public override Vector3 GetLocalScaling(BulletShape pShape) { @@ -1800,160 +2006,131 @@ private sealed class BulletConstraintXNA : BulletConstraint } return false; } - - public static unsafe BulletXNA.CollisionDesc[] GetBulletXNACollisionStruct(byte[] buffer) - { - int count = buffer.Length/sizeof (BulletXNA.CollisionDesc); - BulletXNA.CollisionDesc[] result = new BulletXNA.CollisionDesc[count]; - BulletXNA.CollisionDesc* ptr; - fixed (byte* localBytes = new byte[buffer.Length]) - { - for (int i = 0; i < buffer.Length; i++) - { - localBytes[i] = buffer[i]; - } - for (int i=0;i count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(CollisionDesc) * arrayLength]; - fixed (CollisionDesc* floatPointer = CollisionDescArray) - { - fixed (byte* bytePointer = byteArray) - { - CollisionDesc* read = floatPointer; - CollisionDesc* write = (CollisionDesc*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } - } - return byteArray; - } - public static unsafe byte[] BulletXNACollisionStructToByteArray(BulletXNA.CollisionDesc[] CollisionDescArray, int count) - { - int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(BulletXNA.CollisionDesc) * arrayLength]; - fixed (BulletXNA.CollisionDesc* floatPointer = CollisionDescArray) - { - fixed (byte* bytePointer = byteArray) - { - BulletXNA.CollisionDesc* read = floatPointer; - BulletXNA.CollisionDesc* write = (BulletXNA.CollisionDesc*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } - } - return byteArray; - } - public static unsafe BulletXNA.EntityProperties[] GetBulletXNAEntityStruct(byte[] buffer) - { - int count = buffer.Length / sizeof(BulletXNA.EntityProperties); - BulletXNA.EntityProperties[] result = new BulletXNA.EntityProperties[count]; - BulletXNA.EntityProperties* ptr; - fixed (byte* localBytes = new byte[buffer.Length]) - { - for (int i = 0; i < buffer.Length; i++) - { - localBytes[i] = buffer[i]; - } - for (int i = 0; i < count; i++) - { - ptr = (BulletXNA.EntityProperties*)(localBytes + sizeof(BulletXNA.EntityProperties) * i); - result[i] = new BulletXNA.EntityProperties(); - result[i] = *ptr; - } - } - return result; - } + - public static unsafe EntityProperties[] GetBulletSimEntityStruct(byte[] buffer) + public class SimMotionState : DefaultMotionState { - int count = buffer.Length / sizeof(EntityProperties); - EntityProperties[] result = new EntityProperties[count]; - EntityProperties* ptr; - fixed (byte* localBytes = new byte[buffer.Length]) + public RigidBody Rigidbody; + public Vector3 ZeroVect; + + private IndexedMatrix m_xform; + + private EntityProperties m_properties; + private EntityProperties m_lastProperties; + private BSAPIXNA m_world; + + const float POSITION_TOLERANCE = 0.05f; + const float VELOCITY_TOLERANCE = 0.001f; + const float ROTATION_TOLERANCE = 0.01f; + const float ANGULARVELOCITY_TOLERANCE = 0.01f; + + public SimMotionState(BSAPIXNA pWorld, uint id, IndexedMatrix starTransform, object frameUpdates) { - for (int i = 0; i < buffer.Length; i++) + IndexedQuaternion OrientationQuaterion = starTransform.GetRotation(); + m_properties = new EntityProperties() + { + ID = id, + Position = new Vector3(starTransform._origin.X, starTransform._origin.Y,starTransform._origin.Z), + Rotation = new Quaternion(OrientationQuaterion.X,OrientationQuaterion.Y,OrientationQuaterion.Z,OrientationQuaterion.W) + }; + m_lastProperties = new EntityProperties() { - localBytes[i] = buffer[i]; - } - for (int i = 0; i < count; i++) - { - ptr = (EntityProperties*)(localBytes + sizeof(EntityProperties) * i); - result[i] = new EntityProperties(); - result[i] = *ptr; - } + ID = id, + Position = new Vector3(starTransform._origin.X, starTransform._origin.Y, starTransform._origin.Z), + Rotation = new Quaternion(OrientationQuaterion.X, OrientationQuaterion.Y, OrientationQuaterion.Z, OrientationQuaterion.W) + }; + m_world = pWorld; + m_xform = starTransform; } - return result; - } - public static unsafe byte[] BulletSimEntityStructToByteArray(EntityProperties[] CollisionDescArray, int count) - { - int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(EntityProperties) * arrayLength]; - fixed (EntityProperties* floatPointer = CollisionDescArray) + + public override void GetWorldTransform(out IndexedMatrix worldTrans) { - fixed (byte* bytePointer = byteArray) - { - EntityProperties* read = floatPointer; - EntityProperties* write = (EntityProperties*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } + worldTrans = m_xform; } - return byteArray; - } - public static unsafe byte[] BulletXNAEntityStructToByteArray(BulletXNA.EntityProperties[] CollisionDescArray, int count) - { - int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(BulletXNA.EntityProperties) * arrayLength]; - fixed (BulletXNA.EntityProperties* floatPointer = CollisionDescArray) + + public override void SetWorldTransform(IndexedMatrix worldTrans) { - fixed (byte* bytePointer = byteArray) - { - BulletXNA.EntityProperties* read = floatPointer; - BulletXNA.EntityProperties* write = (BulletXNA.EntityProperties*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } + SetWorldTransform(ref worldTrans); } - return byteArray; + + public override void SetWorldTransform(ref IndexedMatrix worldTrans) + { + SetWorldTransform(ref worldTrans, false); + } + public void SetWorldTransform(ref IndexedMatrix worldTrans, bool force) + { + m_xform = worldTrans; + // Put the new transform into m_properties + IndexedQuaternion OrientationQuaternion = m_xform.GetRotation(); + IndexedVector3 LinearVelocityVector = Rigidbody.GetLinearVelocity(); + IndexedVector3 AngularVelocityVector = Rigidbody.GetAngularVelocity(); + m_properties.Position = new Vector3(m_xform._origin.X, m_xform._origin.Y, m_xform._origin.Z); + m_properties.Rotation = new Quaternion(OrientationQuaternion.X, OrientationQuaternion.Y, + OrientationQuaternion.Z, OrientationQuaternion.W); + // A problem with stock Bullet is that we don't get an event when an object is deactivated. + // This means that the last non-zero values for linear and angular velocity + // are left in the viewer who does dead reconning and the objects look like + // they float off. + // BulletSim ships with a patch to Bullet which creates such an event. + m_properties.Velocity = new Vector3(LinearVelocityVector.X, LinearVelocityVector.Y, LinearVelocityVector.Z); + m_properties.RotationalVelocity = new Vector3(AngularVelocityVector.X, AngularVelocityVector.Y, AngularVelocityVector.Z); + + if (force + + || !AlmostEqual(ref m_lastProperties.Position, ref m_properties.Position, POSITION_TOLERANCE) + || !AlmostEqual(ref m_properties.Rotation, ref m_lastProperties.Rotation, ROTATION_TOLERANCE) + // If the Velocity and AngularVelocity are zero, most likely the object has + // been deactivated. If they both are zero and they have become zero recently, + // make sure a property update is sent so the zeros make it to the viewer. + || ((m_properties.Velocity == ZeroVect && m_properties.RotationalVelocity == ZeroVect) + && + (m_properties.Velocity != m_lastProperties.Velocity || + m_properties.RotationalVelocity != m_lastProperties.RotationalVelocity)) + // If Velocity and AngularVelocity are non-zero but have changed, send an update. + || !AlmostEqual(ref m_properties.Velocity, ref m_lastProperties.Velocity, VELOCITY_TOLERANCE) + || + !AlmostEqual(ref m_properties.RotationalVelocity, ref m_lastProperties.RotationalVelocity, + ANGULARVELOCITY_TOLERANCE) + ) + + + { + // Add this update to the list of updates for this frame. + m_lastProperties = m_properties; + if (m_world.LastEntityProperty < m_world.UpdatedObjects.Length) + m_world.UpdatedObjects[m_world.LastEntityProperty++]=(m_properties); + + //(*m_updatesThisFrame)[m_properties.ID] = &m_properties; + } + + + + + } + public override void SetRigidBody(RigidBody body) + { + Rigidbody = body; + } + internal static bool AlmostEqual(ref Vector3 v1, ref Vector3 v2, float nEpsilon) + { + return + (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) && + (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) && + (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))); + } + + internal static bool AlmostEqual(ref Quaternion v1, ref Quaternion v2, float nEpsilon) + { + return + (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) && + (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) && + (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))) && + (((v1.W - nEpsilon) < v2.W) && (v2.W < (v1.W + nEpsilon))); + } + } } -} + diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fe7891e866..f1ef449313 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1190,8 +1190,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set directly on the vehicle. private void MoveAngular(float pTimestep) { - // VehicleRotationalVelocity = Vector3.Zero; - ComputeAngularTurning(pTimestep); ComputeAngularVerticalAttraction(); @@ -1201,7 +1199,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin ComputeAngularBanking(); // ================================================================== - if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.0001f)) { // The vehicle is not adding anything angular wise. VehicleRotationalVelocity = Vector3.Zero; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 9460daff70..06186b0101 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -334,7 +334,7 @@ public static class BSParam (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , - 0.3f, // set to zero to disable + 0.0f, // set to zero to disable (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return CcdMotionThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, @@ -345,8 +345,8 @@ public static class BSParam (s) => { return CcdSweptSphereRadius; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, (s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ), - new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , - 0.1f, + new ParameterDefn("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" , + 0.0f, (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return ContactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f80084a7fd..8b00a33961 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -363,7 +363,11 @@ public sealed class BSPrim : BSPhysObject // not get it through the terrain _position.Z = targetHeight; if (inTaintTime) + { ForcePosition = _position; + } + // If we are throwing the object around, zero its other forces + ZeroMotion(inTaintTime); ret = true; } @@ -1639,10 +1643,12 @@ public sealed class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. - if (IsPhysical && PositionSanityCheck(true)) + if (IsPhysical && PositionSanityCheck(true /* inTaintTime */ )) { entprop.Position = _position; entprop.Velocity = _velocity; + entprop.RotationalVelocity = _rotationalVelocity; + entprop.Acceleration = _acceleration; } OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 35dba9bb0e..cb304b6737 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -917,8 +917,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters foreach (uint lID in xlIDs) { BSPhysObject theObject = null; - PhysObjects.TryGetValue(lID, out theObject); - thisParam.onObject(this, theObject, xval); + if (PhysObjects.TryGetValue(lID, out theObject)) + thisParam.onObject(this, theObject, xval); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 667cc09cb6..1be2776d94 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -12091,12 +12091,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api radius = Math.Abs(maxY); if (Math.Abs(maxZ) > radius) radius = Math.Abs(maxZ); - + radius = radius*1.413f; Vector3 ac = group.AbsolutePosition - rayStart; Vector3 bc = group.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); - + // Too far off ray, don't bother if (d > radius) return; @@ -12106,11 +12106,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (d2 > 0) return; + ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); EntityIntersection intersection = group.TestIntersection(ray, true, false); // Miss. if (!intersection.HitTF) return; + Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ); + Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ); + //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z); + if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && + intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && + intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) + return; + ContactResult result = new ContactResult (); result.ConsumerID = group.LocalId; // result.Depth = intersection.distance; @@ -12384,8 +12393,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (checkPhysical || checkNonPhysical || detectPhantom) { ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); - foreach (ContactResult r in objectHits) - results.Add(r); + for (int iter = 0; iter < objectHits.Length; iter++) + { + // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler. + objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart); + results.Add(objectHits[iter]); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 002e8529da..9d20c9ec80 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -31,7 +31,6 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.IO; -using System.Linq; using System.Text; using Microsoft.CSharp; //using Microsoft.JScript; diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs index 3243a9a952..6a1112ce41 100644 --- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs +++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -51,7 +52,6 @@ namespace OpenSim.Region.UserStatistics public Hashtable ProcessModel(Hashtable pParams) { - List m_scene = (List)pParams["Scenes"]; Hashtable nh = new Hashtable(); @@ -129,6 +129,86 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// + /// Convert active connections information to JSON string. Returns a structure: + ///
+        /// {"regionName": {
+        ///     "presenceName": {
+        ///         "name": "presenceName",
+        ///         "position": "",
+        ///         "isRoot": "false",
+        ///         "throttle": {
+        ///         },
+        ///         "queue": {
+        ///         }
+        ///     },
+        ///     ... // multiple presences in the scene
+        ///   },
+        ///   ...   // multiple regions in the sim
+        /// }
+        ///
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) + { + List all_scenes = (List) pModelResult["hdata"]; + + OSDMap regionInfo = new OSDMap(); + foreach (Scene scene in all_scenes) + { + OSDMap sceneInfo = new OpenMetaverse.StructuredData.OSDMap(); + List avatarInScene = scene.GetScenePresences(); + foreach (ScenePresence av in avatarInScene) + { + OSDMap presenceInfo = new OSDMap(); + presenceInfo.Add("Name", new OSDString(av.Name)); + + Dictionary queues = new Dictionary(); + if (av.ControllingClient is IStatsCollector) + { + IStatsCollector isClient = (IStatsCollector) av.ControllingClient; + queues = decodeQueueReport(isClient.Report()); + } + OSDMap queueInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (KeyValuePair kvp in queues) { + queueInfo.Add(kvp.Key, new OSDString(kvp.Value)); + } + sceneInfo.Add("queues", queueInfo); + + if (av.IsChildAgent) + presenceInfo.Add("isRoot", new OSDString("false")); + else + presenceInfo.Add("isRoot", new OSDString("true")); + + if (av.AbsolutePosition == DefaultNeighborPosition) + { + presenceInfo.Add("position", new OSDString("<0, 0, 0>")); + } + else + { + presenceInfo.Add("position", new OSDString(string.Format("<{0},{1},{2}>", + (int)av.AbsolutePosition.X, + (int) av.AbsolutePosition.Y, + (int) av.AbsolutePosition.Z)) ); + } + + Dictionary throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); + OSDMap throttleInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (string throttlename in throttles.Keys) + { + throttleInfo.Add(throttlename, new OSDString(throttles[throttlename].ToString())); + } + presenceInfo.Add("throttle", throttleInfo); + + sceneInfo.Add(av.Name, presenceInfo); + } + regionInfo.Add(scene.RegionInfo.RegionName, sceneInfo); + } + return regionInfo.ToString(); + } + public Dictionary DecodeClientThrottles(byte[] throttle) { Dictionary returndict = new Dictionary(); @@ -203,7 +283,7 @@ namespace OpenSim.Region.UserStatistics returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; - returndic.Add("Asset", rep.Substring((7 * pos), 8)); + returndic.Add("Asset", rep.Substring((7 * pos), 8)); /* * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", SendQueue.Count(), diff --git a/OpenSim/Region/UserStatistics/Clients_report.cs b/OpenSim/Region/UserStatistics/Clients_report.cs index b2bb33bf84..4a6f7bea8d 100644 --- a/OpenSim/Region/UserStatistics/Clients_report.cs +++ b/OpenSim/Region/UserStatistics/Clients_report.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.UserStatistics @@ -44,6 +45,32 @@ namespace OpenSim.Region.UserStatistics get { return "Client"; } } + /// + /// Return summar information in the form: + ///
+        /// {"totalUsers": "34",
+        ///  "totalSessions": "233",
+        ///  ...
+        /// }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) { + stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; + + OSDMap summaryInfo = new OpenMetaverse.StructuredData.OSDMap(); + summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); + summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); + summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); + summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); + summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); + summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); + summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); + summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); + return summaryInfo.ToString(); + } + public Hashtable ProcessModel(Hashtable pParams) { SqliteConnection dbConn = (SqliteConnection)pParams["DatabaseConnection"]; diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/UserStatistics/Default_Report.cs index cdc615caff..fabe3d4632 100644 --- a/OpenSim/Region/UserStatistics/Default_Report.cs +++ b/OpenSim/Region/UserStatistics/Default_Report.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -230,6 +231,31 @@ TD.align_top { vertical-align: top; } return returnstruct; } + /// + /// Return summar information in the form: + ///
+        /// {"totalUsers": "34",
+        ///  "totalSessions": "233",
+        ///  ...
+        /// }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) { + stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; + + OSDMap summaryInfo = new OSDMap(); + summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); + summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); + summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); + summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); + summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); + summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); + summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); + summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); + return summaryInfo.ToString(); + } } public struct stats_default_page_values @@ -247,4 +273,5 @@ TD.align_top { vertical-align: top; } public Dictionary sim_stat_data; public Dictionary stats_reports; } + } diff --git a/OpenSim/Region/UserStatistics/IStatsReport.cs b/OpenSim/Region/UserStatistics/IStatsReport.cs index e0ecce4c5c..80c44874e9 100644 --- a/OpenSim/Region/UserStatistics/IStatsReport.cs +++ b/OpenSim/Region/UserStatistics/IStatsReport.cs @@ -34,5 +34,6 @@ namespace OpenSim.Region.UserStatistics string ReportName { get; } Hashtable ProcessModel(Hashtable pParams); string RenderView(Hashtable pModelResult); + string RenderJson(Hashtable pModelResult); } } diff --git a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs index 74de46b227..4d45b80b06 100644 --- a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs +++ b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs @@ -33,6 +33,7 @@ using System.Text; using System.Text.RegularExpressions; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -125,6 +126,34 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// + /// Return the last log lines. Output in the format: + ///
+        /// {"logLines": [
+        /// "line1",
+        /// "line2",
+        /// ...
+        /// ]
+        /// }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) + { + OSDMap logInfo = new OpenMetaverse.StructuredData.OSDMap(); + + OSDArray logLines = new OpenMetaverse.StructuredData.OSDArray(); + string tmp = normalizeEndLines.Replace(pModelResult["loglines"].ToString(), "\n"); + string[] result = Regex.Split(tmp, "\n"); + for (int i = 0; i < result.Length; i++) + { + logLines.Add(new OSDString(result[i])); + } + logInfo.Add("logLines", logLines); + return logInfo.ToString(); + } + #endregion } } diff --git a/OpenSim/Region/UserStatistics/Prototype_distributor.cs b/OpenSim/Region/UserStatistics/Prototype_distributor.cs index 53ae557769..6f8b2aa634 100644 --- a/OpenSim/Region/UserStatistics/Prototype_distributor.cs +++ b/OpenSim/Region/UserStatistics/Prototype_distributor.cs @@ -36,7 +36,18 @@ namespace OpenSim.Region.UserStatistics { public class Prototype_distributor : IStatsController { - private string prototypejs=string.Empty; + private string jsFileName = "prototype.js"; + private string prototypejs = string.Empty; + + public Prototype_distributor() + { + jsFileName = "prototype.js"; + } + + public Prototype_distributor(string jsName) + { + jsFileName = jsName; + } public string ReportName { @@ -45,20 +56,24 @@ namespace OpenSim.Region.UserStatistics public Hashtable ProcessModel(Hashtable pParams) { Hashtable pResult = new Hashtable(); - if (prototypejs.Length == 0) - { - StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open)); - prototypejs = fs.ReadToEnd(); - fs.Close(); - fs.Dispose(); - } - pResult["js"] = prototypejs; + pResult["js"] = jsFileName; return pResult; } public string RenderView(Hashtable pModelResult) { - return pModelResult["js"].ToString(); + string fileName = (string)pModelResult["js"]; + using (StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/" + fileName, FileMode.Open))) + { + prototypejs = fs.ReadToEnd(); + fs.Close(); + } + return prototypejs; + } + + public string RenderJson(Hashtable pModelResult) + { + return "{}"; } } diff --git a/OpenSim/Region/UserStatistics/Sessions_Report.cs b/OpenSim/Region/UserStatistics/Sessions_Report.cs index 1a2d460c76..0e94912ee4 100644 --- a/OpenSim/Region/UserStatistics/Sessions_Report.cs +++ b/OpenSim/Region/UserStatistics/Sessions_Report.cs @@ -278,6 +278,11 @@ TD.align_top { vertical-align: top; } public DateTime start_time; } + public string RenderJson(Hashtable pModelResult) + { + return "{}"; + } #endregion } + } diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs index 28051fb674..ad848a1330 100644 --- a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs +++ b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -218,6 +219,64 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// + /// Return stat information for all regions in the sim. Returns data of the form: + ///
+        /// {"REGIONNAME": {
+        ///     "region": "REGIONNAME",
+        ///     "timeDilation": "101", 
+        ///     ...     // the rest of the stat info
+        ///     },
+        ///  ...    // entries for each region
+        ///  }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) + { + List all_scenes = (List) pModelResult["hdata"]; + Dictionary sdatadic = (Dictionary)pModelResult["simstats"]; + + OSDMap allStatsInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (USimStatsData sdata in sdatadic.Values) + { + OSDMap statsInfo = new OpenMetaverse.StructuredData.OSDMap(); + string regionName = "unknown"; + foreach (Scene sn in all_scenes) + { + if (sn.RegionInfo.RegionID == sdata.RegionId) + { + regionName = sn.RegionInfo.RegionName; + break; + } + } + statsInfo.Add("region", new OSDString(regionName)); + statsInfo.Add("timeDilation", new OSDString(sdata.TimeDilation.ToString())); + statsInfo.Add("simFPS", new OSDString(sdata.SimFps.ToString())); + statsInfo.Add("physicsFPS", new OSDString(sdata.PhysicsFps.ToString())); + statsInfo.Add("agentUpdates", new OSDString(sdata.AgentUpdates.ToString())); + statsInfo.Add("rootAgents", new OSDString(sdata.RootAgents.ToString())); + statsInfo.Add("childAgents", new OSDString(sdata.ChildAgents.ToString())); + statsInfo.Add("totalPrims", new OSDString(sdata.TotalPrims.ToString())); + statsInfo.Add("activePrims", new OSDString(sdata.ActivePrims.ToString())); + statsInfo.Add("activeScripts", new OSDString(sdata.ActiveScripts.ToString())); + statsInfo.Add("scriptLinesPerSec", new OSDString(sdata.ScriptLinesPerSecond.ToString())); + statsInfo.Add("totalFrameTime", new OSDString(sdata.TotalFrameTime.ToString())); + statsInfo.Add("agentFrameTime", new OSDString(sdata.AgentFrameTime.ToString())); + statsInfo.Add("physicsFrameTime", new OSDString(sdata.PhysicsFrameTime.ToString())); + statsInfo.Add("otherFrameTime", new OSDString(sdata.OtherFrameTime.ToString())); + statsInfo.Add("outPacketsPerSec", new OSDString(sdata.OutPacketsPerSecond.ToString())); + statsInfo.Add("inPacketsPerSec", new OSDString(sdata.InPacketsPerSecond.ToString())); + statsInfo.Add("unackedByptes", new OSDString(sdata.UnackedBytes.ToString())); + statsInfo.Add("pendingDownloads", new OSDString(sdata.PendingDownloads.ToString())); + statsInfo.Add("pendingUploads", new OSDString(sdata.PendingUploads.ToString())); + + allStatsInfo.Add(regionName, statsInfo); + } + return allStatsInfo.ToString(); + } + #endregion } } diff --git a/OpenSim/Region/UserStatistics/Updater_distributor.cs b/OpenSim/Region/UserStatistics/Updater_distributor.cs index 9593cc915c..601e06b65c 100644 --- a/OpenSim/Region/UserStatistics/Updater_distributor.cs +++ b/OpenSim/Region/UserStatistics/Updater_distributor.cs @@ -62,5 +62,9 @@ namespace OpenSim.Region.UserStatistics return pModelResult["js"].ToString(); } + public string RenderJson(Hashtable pModelResult) { + return "{}"; + } + } } \ No newline at end of file diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 64cb577350..438ef485ab 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -121,6 +121,10 @@ namespace OpenSim.Region.UserStatistics reports.Add("clients.report", clientReport); reports.Add("sessions.report", sessionsReport); + reports.Add("sim.css", new Prototype_distributor("sim.css")); + reports.Add("sim.html", new Prototype_distributor("sim.html")); + reports.Add("jquery.js", new Prototype_distributor("jquery.js")); + //// // Add Your own Reports here (Do Not Modify Lines here Devs!) //// @@ -255,9 +259,12 @@ namespace OpenSim.Region.UserStatistics string regpath = request["uri"].ToString(); int response_code = 404; string contenttype = "text/html"; + bool jsonFormatOutput = false; string strOut = string.Empty; + // The request patch should be "/SStats/reportName" where 'reportName' + // is one of the names added to the 'reports' hashmap. regpath = regpath.Remove(0, 8); if (regpath.Length == 0) regpath = "default.report"; if (reports.ContainsKey(regpath)) @@ -265,6 +272,9 @@ namespace OpenSim.Region.UserStatistics IStatsController rep = reports[regpath]; Hashtable repParams = new Hashtable(); + if (request.ContainsKey("json")) + jsonFormatOutput = true; + if (request.ContainsKey("requestvars")) repParams["RequestVars"] = request["requestvars"]; else @@ -284,13 +294,26 @@ namespace OpenSim.Region.UserStatistics concurrencyCounter++; - strOut = rep.RenderView(rep.ProcessModel(repParams)); + if (jsonFormatOutput) + { + strOut = rep.RenderJson(rep.ProcessModel(repParams)); + contenttype = "text/json"; + } + else + { + strOut = rep.RenderView(rep.ProcessModel(repParams)); + } if (regpath.EndsWith("js")) { contenttype = "text/javascript"; } + if (regpath.EndsWith("css")) + { + contenttype = "text/css"; + } + concurrencyCounter--; response_code = 200; diff --git a/bin/BulletXNA.dll b/bin/BulletXNA.dll index 5e69b2e28b..bfaac4fa6d 100644 Binary files a/bin/BulletXNA.dll and b/bin/BulletXNA.dll differ diff --git a/bin/BulletXNA.pdb b/bin/BulletXNA.pdb index 3d4906f44d..ecab22fbb5 100644 Binary files a/bin/BulletXNA.pdb and b/bin/BulletXNA.pdb differ diff --git a/bin/data/LICENSE-README-IMPORTANT.txt b/bin/data/LICENSE-README-IMPORTANT.txt index 86e401f302..a1ac20cf05 100644 --- a/bin/data/LICENSE-README-IMPORTANT.txt +++ b/bin/data/LICENSE-README-IMPORTANT.txt @@ -2,4 +2,4 @@ Not all of the files in this directory are licensed under the BSD license. Some These files are: -- avataranimations.xml (Derivative work of viewerart.ini, Creative Commons Attribution+Share-Alike v2.5 License) \ No newline at end of file +- avataranimations.xml (Derivative work of viewerart.ini, Creative Commons Attribution+Share-Alike v2.5 License) diff --git a/bin/data/sim.css b/bin/data/sim.css new file mode 100644 index 0000000000..e584a1ab44 --- /dev/null +++ b/bin/data/sim.css @@ -0,0 +1,85 @@ +body { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-size: 12px; + background: #4A5F6D; + color: #EEEAD6; + padding: 0px; + margin: 0px; +} +.footer { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-size: 10px; +} +td { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-size: 12px; + padding: 4px; + margin: 4px; +} +blockquote { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-style: italic; + font-size: 12px; +} +pre { + padding: 5px; + background-color: #8080B0; + color: #000000; + margin-left: 20px; + font-size: 11px; +} +:link { + color: #ffffff; +} +:visited { + color: #d0d0d0; +} +.SimSectionHeader { + font-size: 120%; +} +div.SimSectionContainer { + padding: 10px 0px 0px 20px; +} +/* SimStats ===================================== */ +#SimSimStats div { + margin-left: 20px; + background: #3A4F5D; +} +#SimSimStats table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} +/* Region Stats ===================================== */ +#SimRegionStats div { + margin-left: 20px; + background: #3A4F5D; +} +#SimRegionStats table { + border: 1px; + border-style: solid; +} +#SimRegionStats table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} +/* Session Stats ===================================== */ +#SimSessionStats div { + margin-left: 20px; + background: #3A4F5D; +} +#SimSessionStats table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} +/* LogFile ===================================== */ +#SimLogFile div { + margin-left: 20px; +} +#SimLogFile table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} diff --git a/bin/data/sim.html b/bin/data/sim.html new file mode 100644 index 0000000000..82d4789caa --- /dev/null +++ b/bin/data/sim.html @@ -0,0 +1,291 @@ + + + +Simulator statistics + + + + + + + + + +
+
+ + + + + +
+Region Stats +
+
+
+ + +
+Sessions +
+
+
+ + +
+Log File +
+
+
+ + +
+
+
+ +