From 302d72701da35b6d481a538c4cb953976d7e9044 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 20 Jun 2011 17:14:59 -0700 Subject: BulletSim initial checkin --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 426 +++++ OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 951 ++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs | 68 + OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 1192 +++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 553 ++++++ .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 186 ++ .../Physics/ConvexDecompositionDotNet/CTri.cs | 341 ++++ .../Physics/ConvexDecompositionDotNet/Concavity.cs | 233 +++ .../ConvexDecompositionDotNet/ConvexBuilder.cs | 411 +++++ .../ConvexDecomposition.cs | 200 +++ .../ConvexDecompositionDotNet/ConvexResult.cs | 74 + .../ConvexDecompositionDotNet/HullClasses.cs | 171 ++ .../ConvexDecompositionDotNet/HullTriangle.cs | 99 ++ .../Physics/ConvexDecompositionDotNet/HullUtils.cs | 1868 ++++++++++++++++++++ .../Physics/ConvexDecompositionDotNet/LICENSE.txt | 28 + .../Physics/ConvexDecompositionDotNet/Plane.cs | 99 ++ .../Physics/ConvexDecompositionDotNet/PlaneTri.cs | 211 +++ .../Properties/AssemblyInfo.cs | 36 + .../ConvexDecompositionDotNet/Quaternion.cs | 209 +++ .../Physics/ConvexDecompositionDotNet/README.txt | 7 + .../ConvexDecompositionDotNet/SplitPlane.cs | 265 +++ .../ConvexDecompositionDotNet/VertexLookup.cs | 70 + .../Physics/ConvexDecompositionDotNet/float2.cs | 70 + .../Physics/ConvexDecompositionDotNet/float3.cs | 444 +++++ .../Physics/ConvexDecompositionDotNet/float3x3.cs | 195 ++ .../Physics/ConvexDecompositionDotNet/float4.cs | 170 ++ .../Physics/ConvexDecompositionDotNet/float4x4.cs | 284 +++ .../Physics/ConvexDecompositionDotNet/int3.cs | 128 ++ .../Physics/ConvexDecompositionDotNet/int4.cs | 66 + 29 files changed, 9055 insertions(+) create mode 100644 OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs create mode 100644 OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs create mode 100644 OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs create mode 100644 OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs create mode 100644 OpenSim/Region/Physics/BulletSPlugin/BSScene.cs create mode 100644 OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs create mode 100644 OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs new file mode 100644 index 0000000..d9e236f --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -0,0 +1,426 @@ +/* + * 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 copyrightD + * 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 System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public class BSCharacter : PhysicsActor +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[BULLETS CHAR]"; + + private BSScene _scene; + private String _avName; + private bool _stopped; + private Vector3 _size; + private Vector3 _scale; + private PrimitiveBaseShape _pbs; + private uint _localID = 0; + private bool _grabbed; + private bool _selected; + private Vector3 _position; + private float _mass = 80f; + public float _density = 60f; + public float CAPSULE_RADIUS = 0.37f; + public float CAPSULE_LENGTH = 2.140599f; + private Vector3 _force; + private Vector3 _velocity; + private Vector3 _torque; + private float _collisionScore; + private Vector3 _acceleration; + private Quaternion _orientation; + private int _physicsActorType; + private bool _isPhysical; + private bool _flying; + private bool _setAlwaysRun; + private bool _throttleUpdates; + private bool _isColliding; + private long _collidingStep; + private bool _collidingGround; + private long _collidingGroundStep; + private bool _collidingObj; + private bool _floatOnWater; + private Vector3 _rotationalVelocity; + private bool _kinematic; + private float _buoyancy; + + private int _subscribedEventsMs = 0; + private int _lastCollisionTime = 0; + + private Vector3 _PIDTarget; + private bool _usePID; + private float _PIDTau; + private bool _useHoverPID; + private float _PIDHoverHeight; + private PIDHoverType _PIDHoverType; + private float _PIDHoverTao; + + public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying) + { + _localID = localID; + _avName = avName; + _scene = parent_scene; + _position = pos; + _size = size; + _orientation = Quaternion.Identity; + _velocity = Vector3.Zero; + _buoyancy = 0f; // characters return a buoyancy of zero + _scale = new Vector3(1f, 1f, 1f); + float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH); + _mass = _density*AVvolume; + + ShapeData shapeData = new ShapeData(); + shapeData.ID = _localID; + shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; + shapeData.Position = _position; + shapeData.Rotation = _orientation; + shapeData.Velocity = _velocity; + shapeData.Scale = _scale; + shapeData.Mass = _mass; + shapeData.Buoyancy = isFlying ? 0f : 1f; + shapeData.Static = ShapeData.numericFalse; + + // do actual create at taint time + _scene.TaintedObject(delegate() + { + BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); + }); + + return; + } + + // called when this character is being destroyed and the resources should be released + public void Destroy() + { + _scene.TaintedObject(delegate() + { + BulletSimAPI.DestroyObject(_scene.WorldID, _localID); + }); + } + + public override void RequestPhysicsterseUpdate() + { + base.RequestPhysicsterseUpdate(); + } + + public override bool Stopped { + get { return _stopped; } + } + public override Vector3 Size { + get { return _size; } + set { _size = value; + } + } + public override PrimitiveBaseShape Shape { + set { _pbs = value; + } + } + public override uint LocalID { + set { _localID = value; + } + get { return _localID; } + } + public override bool Grabbed { + set { _grabbed = value; + } + } + public override bool Selected { + set { _selected = value; + } + } + public override void CrossingFailure() { return; } + public override void link(PhysicsActor obj) { return; } + public override void delink() { return; } + public override void LockAngularMotion(Vector3 axis) { return; } + + public override Vector3 Position { + get { + // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + return _position; + } + set { + _position = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); + }); + } + } + public override float Mass { + get { + return _mass; + } + } + public override Vector3 Force { + get { return _force; } + set { + _force = value; + m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); + }); + } + } + + public override int VehicleType { + get { return 0; } + set { return; } + } + public override void VehicleFloatParam(int param, float value) { } + public override void VehicleVectorParam(int param, Vector3 value) {} + public override void VehicleRotationParam(int param, Quaternion rotation) { } + public override void VehicleFlags(int param, bool remove) { } + + // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more + public override void SetVolumeDetect(int param) { return; } + + public override Vector3 GeometricCenter { get { return Vector3.Zero; } } + public override Vector3 CenterOfMass { get { return Vector3.Zero; } } + public override Vector3 Velocity { + get { return _velocity; } + set { + _velocity = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); + }); + } + } + public override Vector3 Torque { + get { return _torque; } + set { _torque = value; + } + } + public override float CollisionScore { + get { return _collisionScore; } + set { _collisionScore = value; + } + } + public override Vector3 Acceleration { + get { return _acceleration; } + } + public override Quaternion Orientation { + get { return _orientation; } + set { + _orientation = value; + _scene.TaintedObject(delegate() + { + // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); + }); + } + } + public override int PhysicsActorType { + get { return _physicsActorType; } + set { _physicsActorType = value; + } + } + public override bool IsPhysical { + get { return _isPhysical; } + set { _isPhysical = value; + } + } + public override bool Flying { + get { return _flying; } + set { + _flying = value; + _scene.TaintedObject(delegate() + { + // simulate flying by changing the effect of gravity + BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 0f : 1f); + }); + } + } + public override bool + SetAlwaysRun { + get { return _setAlwaysRun; } + set { _setAlwaysRun = value; } + } + public override bool ThrottleUpdates { + get { return _throttleUpdates; } + set { _throttleUpdates = value; } + } + public override bool IsColliding { + get { return (_collidingStep == _scene.SimulationStep); } + set { _isColliding = value; } + } + public override bool CollidingGround { + get { return (_collidingGroundStep == _scene.SimulationStep); } + set { _collidingGround = value; } + } + public override bool CollidingObj { + get { return _collidingObj; } + set { _collidingObj = value; } + } + public override bool FloatOnWater { + set { _floatOnWater = value; } + } + public override Vector3 RotationalVelocity { + get { return _rotationalVelocity; } + set { _rotationalVelocity = value; } + } + public override bool Kinematic { + get { return _kinematic; } + set { _kinematic = value; } + } + public override float Buoyancy { + get { return _buoyancy; } + set { _buoyancy = value; } + } + + // Used for MoveTo + public override Vector3 PIDTarget { + set { _PIDTarget = value; } + } + public override bool PIDActive { + set { _usePID = value; } + } + public override float PIDTau { + set { _PIDTau = value; } + } + + // Used for llSetHoverHeight and maybe vehicle height + // Hover Height will override MoveTo target's Z + public override bool PIDHoverActive { + set { _useHoverPID = value; } + } + public override float PIDHoverHeight { + set { _PIDHoverHeight = value; } + } + public override PIDHoverType PIDHoverType { + set { _PIDHoverType = value; } + } + public override float PIDHoverTau { + set { _PIDHoverTao = value; } + } + + // For RotLookAt + public override Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + + public override void AddForce(Vector3 force, bool pushforce) { + if (force.IsFinite()) + { + _force.X += force.X; + _force.Y += force.Y; + _force.Z += force.Z; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); + }); + } + else + { + m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); + } + //m_lastUpdateSent = false; + } + public override void AddAngularForce(Vector3 force, bool pushforce) { + } + public override void SetMomentum(Vector3 momentum) { + } + public override void SubscribeEvents(int ms) { + _subscribedEventsMs = ms; + _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen + } + public override void UnSubscribeEvents() { + _subscribedEventsMs = 0; + } + public override bool SubscribedEvents() { + return (_subscribedEventsMs > 0); + } + + // The physics engine says that properties have updated. Update same and inform + // the world that things have changed. + public void UpdateProperties(EntityProperties entprop) + { + bool changed = false; + // we assign to the local variables so the normal set action does not happen + if (_position != entprop.Position) + { + _position = entprop.Position; + changed = true; + } + if (_orientation != entprop.Rotation) + { + _orientation = entprop.Rotation; + changed = true; + } + if (_velocity != entprop.Velocity) + { + _velocity = entprop.Velocity; + changed = true; + } + if (_acceleration != entprop.Acceleration) + { + _acceleration = entprop.Acceleration; + changed = true; + } + if (_rotationalVelocity != entprop.AngularVelocity) + { + _rotationalVelocity = entprop.AngularVelocity; + changed = true; + } + if (changed) + { + // base.RequestPhysicsterseUpdate(); + } + } + + public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) + { + // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); + + // The following makes IsColliding() and IsCollidingGround() work + _collidingStep = _scene.SimulationStep; + if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) + { + _collidingGroundStep = _scene.SimulationStep; + } + + if (_subscribedEventsMs == 0) return; // don't want collisions + int nowTime = Util.EnvironmentTickCount(); + if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; + _lastCollisionTime = nowTime; + + Dictionary contactPoints = new Dictionary(); + contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints); + base.SendCollisionUpdate(args); + } + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs new file mode 100644 index 0000000..046726d --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -0,0 +1,951 @@ +/* + * 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. + */ + +/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to + * call the BulletSim system. + */ +/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + public class BSDynamics + { + private int frcount = 0; // Used to limit dynamics debug output to + // every 100th frame + + // private BSScene m_parentScene = null; + private BSPrim m_prim; // the prim this dynamic controller belongs to + + // Vehicle properties + private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind + public Vehicle Type + { + get { return m_type; } + } + // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier + private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: + // HOVER_TERRAIN_ONLY + // HOVER_GLOBAL_HEIGHT + // NO_DEFLECTION_UP + // HOVER_WATER_ONLY + // HOVER_UP_ONLY + // LIMIT_MOTOR_UP + // LIMIT_ROLL_ONLY + private VehicleFlag m_Hoverflags = (VehicleFlag)0; + private Vector3 m_BlockingEndPoint = Vector3.Zero; + private Quaternion m_RollreferenceFrame = Quaternion.Identity; + // Linear properties + private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time + private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL + private Vector3 m_dir = Vector3.Zero; // velocity applied to body + private Vector3 m_linearFrictionTimescale = Vector3.Zero; + private float m_linearMotorDecayTimescale = 0; + private float m_linearMotorTimescale = 0; + private Vector3 m_lastLinearVelocityVector = Vector3.Zero; + private Vector3 m_lastPositionVector = Vector3.Zero; + // private bool m_LinearMotorSetLastFrame = false; + // private Vector3 m_linearMotorOffset = Vector3.Zero; + + //Angular properties + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + private int m_angularMotorApply = 0; // application frame counter + private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity + private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate + private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate + private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + // private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body + + //Deflection properties + // private float m_angularDeflectionEfficiency = 0; + // private float m_angularDeflectionTimescale = 0; + // private float m_linearDeflectionEfficiency = 0; + // private float m_linearDeflectionTimescale = 0; + + //Banking properties + // private float m_bankingEfficiency = 0; + // private float m_bankingMix = 0; + // private float m_bankingTimescale = 0; + + //Hover and Buoyancy properties + private float m_VhoverHeight = 0f; +// private float m_VhoverEfficiency = 0f; + private float m_VhoverTimescale = 0f; + private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height + private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. + // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + + //Attractor properties + private float m_verticalAttractionEfficiency = 1.0f; // damped + private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + + public BSDynamics(BSPrim myPrim) + { + m_prim = myPrim; + m_type = Vehicle.TYPE_NONE; + } + + internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) + { + switch (pParam) + { + case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionEfficiency = pValue; + break; + case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorDecayTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorTimescale = pValue; + break; + case Vehicle.BANKING_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingEfficiency = pValue; + break; + case Vehicle.BANKING_MIX: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingMix = pValue; + break; + case Vehicle.BANKING_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingTimescale = pValue; + break; + case Vehicle.BUOYANCY: + if (pValue < -1f) pValue = -1f; + if (pValue > 1f) pValue = 1f; + m_VehicleBuoyancy = pValue; + break; +// case Vehicle.HOVER_EFFICIENCY: +// if (pValue < 0f) pValue = 0f; +// if (pValue > 1f) pValue = 1f; +// m_VhoverEfficiency = pValue; +// break; + case Vehicle.HOVER_HEIGHT: + m_VhoverHeight = pValue; + break; + case Vehicle.HOVER_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_VhoverTimescale = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionEfficiency = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorDecayTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorTimescale = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: + if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable + if (pValue > 1.0f) pValue = 1.0f; + m_verticalAttractionEfficiency = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_verticalAttractionTimescale = pValue; + break; + + // These are vector properties but the engine lets you use a single float value to + // set all of the components to the same value + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue, pValue, pValue); + m_angularMotorApply = 10; + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue, pValue, pValue); + m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); + break; + + } + }//end ProcessFloatVehicleParam + + internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) + { + switch (pParam) + { + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + // Limit requested angular speed to 2 rps= 4 pi rads/sec + if (m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; + if (m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; + if (m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; + if (m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; + if (m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; + if (m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; + m_angularMotorApply = 10; + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.BLOCK_EXIT: + m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + } + }//end ProcessVectorVehicleParam + + internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) + { + switch (pParam) + { + case Vehicle.REFERENCE_FRAME: + // m_referenceFrame = pValue; + break; + case Vehicle.ROLL_FRAME: + m_RollreferenceFrame = pValue; + break; + } + }//end ProcessRotationVehicleParam + + internal void ProcessVehicleFlags(int pParam, bool remove) + { + if (remove) + { + if (pParam == -1) + { + m_flags = (VehicleFlag)0; + m_Hoverflags = (VehicleFlag)0; + return; + } + if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) + { + if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0) + m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT); + } + if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY) + { + if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0) + m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY); + } + if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY) + { + if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0) + m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY); + } + if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY) + { + if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0) + m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY); + } + if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP) + { + if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP); + } + if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY) + { + if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); + } + if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK) + { + if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.MOUSELOOK_BANK); + } + if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER) + { + if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.MOUSELOOK_STEER); + } + if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP) + { + if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP); + } + if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED) + { + if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED); + } + if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X) + { + if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.NO_X); + } + if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y) + { + if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.NO_Y); + } + if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z) + { + if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.NO_Z); + } + if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT) + { + if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0) + m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT); + } + if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION) + { + if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.NO_DEFLECTION); + } + if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION) + { + if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) + m_flags &= ~(VehicleFlag.LOCK_ROTATION); + } + } + else + { + if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) + { + m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags); + } + if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY) + { + m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags); + } + if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY) + { + m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags); + } + if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY) + { + m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags); + } + if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP) + { + m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags); + } + if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK) + { + m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags); + } + if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER) + { + m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags); + } + if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP) + { + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags); + } + if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED) + { + m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags); + } + if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X) + { + m_flags |= (VehicleFlag.NO_X); + } + if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y) + { + m_flags |= (VehicleFlag.NO_Y); + } + if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z) + { + m_flags |= (VehicleFlag.NO_Z); + } + if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT) + { + m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT); + } + if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION) + { + m_flags |= (VehicleFlag.NO_DEFLECTION); + } + if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION) + { + m_flags |= (VehicleFlag.LOCK_ROTATION); + } + } + }//end ProcessVehicleFlags + + internal void ProcessTypeChange(Vehicle pType) + { + // Set Defaults For Type + m_type = pType; + switch (pType) + { + case Vehicle.TYPE_NONE: + m_linearFrictionTimescale = new Vector3(0, 0, 0); + m_angularFrictionTimescale = new Vector3(0, 0, 0); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 0; + m_linearMotorDecayTimescale = 0; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 0; + m_angularMotorDecayTimescale = 0; + m_VhoverHeight = 0; + m_VhoverTimescale = 0; + m_VehicleBuoyancy = 0; + m_flags = (VehicleFlag)0; + break; + + case Vehicle.TYPE_SLED: + m_linearFrictionTimescale = new Vector3(30, 1, 1000); + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1000; + m_linearMotorDecayTimescale = 120; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1000; + m_angularMotorDecayTimescale = 120; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 1; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 1; + // m_linearDeflectionTimescale = 1; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 1000; + // m_bankingEfficiency = 0; + // m_bankingMix = 1; + // m_bankingTimescale = 10; + // m_referenceFrame = Quaternion.Identity; + m_Hoverflags &= + ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_CAR: + m_linearFrictionTimescale = new Vector3(100, 2, 1000); + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1; + m_angularMotorDecayTimescale = 0.8f; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // // m_linearDeflectionEfficiency = 1; + // // m_linearDeflectionTimescale = 2; + // // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 10; + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 10f; + // m_bankingEfficiency = -0.2f; + // m_bankingMix = 1; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); + break; + case Vehicle.TYPE_BOAT: + m_linearFrictionTimescale = new Vector3(10, 3, 2); + m_angularFrictionTimescale = new Vector3(10,10,10); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 2; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 0.5f; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 0.5f; + m_verticalAttractionTimescale = 5f; + // m_bankingEfficiency = -0.3f; + // m_bankingMix = 0.8f; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | + VehicleFlag.LIMIT_MOTOR_UP); + m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); + break; + case Vehicle.TYPE_AIRPLANE: + m_linearFrictionTimescale = new Vector3(200, 10, 5); + m_angularFrictionTimescale = new Vector3(20, 20, 20); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 2; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 2; + m_verticalAttractionEfficiency = 0.9f; + m_verticalAttractionTimescale = 2f; + // m_bankingEfficiency = 1; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 2; + // m_referenceFrame = Quaternion.Identity; + m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); + break; + case Vehicle.TYPE_BALLOON: + m_linearFrictionTimescale = new Vector3(5, 5, 5); + m_angularFrictionTimescale = new Vector3(10, 10, 10); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 6; + m_angularMotorDecayTimescale = 10; + m_VhoverHeight = 5; +// m_VhoverEfficiency = 0.8f; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0; + // m_linearDeflectionTimescale = 5; + // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 100f; + // m_bankingEfficiency = 0; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 5; + // m_referenceFrame = Quaternion.Identity; + m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_UP_ONLY); + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); + m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); + break; + + } + }//end SetDefaultsForType + + internal void Step(float pTimestep, BSScene pParentScene) + { + if (m_type == Vehicle.TYPE_NONE) return; + + frcount++; // used to limit debug comment output + if (frcount > 100) + frcount = 0; + + MoveLinear(pTimestep, pParentScene); + MoveAngular(pTimestep); + LimitRotation(pTimestep); + }// end Step + + private void MoveLinear(float pTimestep, BSScene _pParentScene) + { + if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant + { + // add drive to body + Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); + m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? + + // This will work temporarily, but we really need to compare speed on an axis + // KF: Limit body velocity to applied velocity? + if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) + m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; + if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) + m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; + if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) + m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; + + // decay applied velocity + Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); + //Console.WriteLine("decay: " + decayfraction); + m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; + //Console.WriteLine("actual: " + m_linearMotorDirection); + } + else + { // requested is not significant + // if what remains of applied is small, zero it. + if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) + m_lastLinearVelocityVector = Vector3.Zero; + } + + // convert requested object velocity to world-referenced vector + m_dir = m_lastLinearVelocityVector; + Quaternion rot = m_prim.Orientation; + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object + m_dir *= rotq; // apply obj rotation to velocity vector + + // add Gravity andBuoyancy + // KF: So far I have found no good method to combine a script-requested + // .Z velocity and gravity. Therefore only 0g will used script-requested + // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. + Vector3 grav = Vector3.Zero; + // There is some gravity, make a gravity force vector + // that is applied after object velocity. + float objMass = m_prim.Mass; + // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; + grav.Z = _pParentScene.DefaultGravity.Z * objMass * (1f - m_VehicleBuoyancy); + // Preserve the current Z velocity + Vector3 vel_now = m_prim.Velocity; + m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity + + Vector3 pos = m_prim.Position; +// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); + Vector3 posChange = new Vector3(); + posChange.X = pos.X - m_lastPositionVector.X; + posChange.Y = pos.Y - m_lastPositionVector.Y; + posChange.Z = pos.Z - m_lastPositionVector.Z; + double Zchange = Math.Abs(posChange.Z); + if (m_BlockingEndPoint != Vector3.Zero) + { + if (pos.X >= (m_BlockingEndPoint.X - (float)1)) + { + pos.X -= posChange.X + 1; + m_prim.Position = pos; + } + if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) + { + pos.Y -= posChange.Y + 1; + m_prim.Position = pos; + } + if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) + { + pos.Z -= posChange.Z + 1; + m_prim.Position = pos; + } + if (pos.X <= 0) + { + pos.X += posChange.X + 1; + m_prim.Position = pos; + } + if (pos.Y <= 0) + { + pos.Y += posChange.Y + 1; + m_prim.Position = pos; + } + } + if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y)) + { + pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2; + m_prim.Position = pos; + } + + // Check if hovering + if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) + { + // We should hover, get the target height + if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) + { + m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; + } + if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) + { + m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; + } + if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) + { + m_VhoverTargetHeight = m_VhoverHeight; + } + + if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) + { + // If body is aready heigher, use its height as target height + if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; + } + if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) + { + if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) + { + m_prim.Position = pos; + } + } + else + { + float herr0 = pos.Z - m_VhoverTargetHeight; + // Replace Vertical speed with correction figure if significant + if (Math.Abs(herr0) > 0.01f) + { + m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); + //KF: m_VhoverEfficiency is not yet implemented + } + else + { + m_dir.Z = 0f; + } + } + +// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped +// m_VhoverTimescale = 0f; // time to acheive height +// pTimestep is time since last frame,in secs + } + + if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) + { + //Start Experimental Values + if (Zchange > .3) + { + grav.Z = (float)(grav.Z * 3); + } + if (Zchange > .15) + { + grav.Z = (float)(grav.Z * 2); + } + if (Zchange > .75) + { + grav.Z = (float)(grav.Z * 1.5); + } + if (Zchange > .05) + { + grav.Z = (float)(grav.Z * 1.25); + } + if (Zchange > .025) + { + grav.Z = (float)(grav.Z * 1.125); + } + float terraintemp = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); + float postemp = (pos.Z - terraintemp); + if (postemp > 2.5f) + { + grav.Z = (float)(grav.Z * 1.037125); + } + //End Experimental Values + } + if ((m_flags & (VehicleFlag.NO_X)) != 0) + { + m_dir.X = 0; + } + if ((m_flags & (VehicleFlag.NO_Y)) != 0) + { + m_dir.Y = 0; + } + if ((m_flags & (VehicleFlag.NO_Z)) != 0) + { + m_dir.Z = 0; + } + + m_lastPositionVector = m_prim.Position; + + // Apply velocity + m_prim.Velocity = m_dir; + // apply gravity force + m_prim.Force = grav; + + + // apply friction + Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); + m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; + } // end MoveLinear() + + private void MoveAngular(float pTimestep) + { + /* + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + private int m_angularMotorApply = 0; // application frame counter + private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down) + private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate + private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate + private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + */ + + // Get what the body is doing, this includes 'external' influences + Vector3 angularVelocity = m_prim.AngularVelocity; + // Vector3 angularVelocity = Vector3.Zero; + + if (m_angularMotorApply > 0) + { + // ramp up to new value + // current velocity += error / (time to get there / step interval) + // requested speed - last motor speed + m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); + m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); + m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); + + m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected + // velocity may still be acheived. + } + else + { + // no motor recently applied, keep the body velocity + /* m_angularMotorVelocity.X = angularVelocity.X; + m_angularMotorVelocity.Y = angularVelocity.Y; + m_angularMotorVelocity.Z = angularVelocity.Z; */ + + // and decay the velocity + m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); + } // end motor section + + // Vertical attractor section + Vector3 vertattr = Vector3.Zero; + + if (m_verticalAttractionTimescale < 300) + { + float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); + // get present body rotation + Quaternion rotq = m_prim.Orientation; + // make a vector pointing up + Vector3 verterr = Vector3.Zero; + verterr.Z = 1.0f; + // rotate it to Body Angle + verterr = verterr * rotq; + // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. + // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go + // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. + if (verterr.Z < 0.0f) + { + verterr.X = 2.0f - verterr.X; + verterr.Y = 2.0f - verterr.Y; + } + // Error is 0 (no error) to +/- 2 (max error) + // scale it by VAservo + verterr = verterr * VAservo; +//if (frcount == 0) Console.WriteLine("VAerr=" + verterr); + + // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so + // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. + vertattr.X = verterr.Y; + vertattr.Y = - verterr.X; + vertattr.Z = 0f; + + // scaling appears better usingsquare-law + float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + vertattr.X += bounce * angularVelocity.X; + vertattr.Y += bounce * angularVelocity.Y; + + } // else vertical attractor is off + + // m_lastVertAttractor = vertattr; + + // Bank section tba + // Deflection section tba + + // Sum velocities + m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection + + if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + { + m_lastAngularVelocity.X = 0; + m_lastAngularVelocity.Y = 0; + } + + if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. + } + + // apply friction + Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); + m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; + + // Apply to the body + m_prim.AngularVelocity = m_lastAngularVelocity; + + } //end MoveAngular + internal void LimitRotation(float timestep) + { + Quaternion rotq = m_prim.Orientation; // rotq = rotation of object + Quaternion m_rot = rotq; + bool changed = false; + if (m_RollreferenceFrame != Quaternion.Identity) + { + if (rotq.X >= m_RollreferenceFrame.X) + { + m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); + } + if (rotq.Y >= m_RollreferenceFrame.Y) + { + m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); + } + if (rotq.X <= -m_RollreferenceFrame.X) + { + m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); + } + if (rotq.Y <= -m_RollreferenceFrame.Y) + { + m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); + } + changed = true; + } + if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) + { + m_rot.X = 0; + m_rot.Y = 0; + changed = true; + } + if (changed) + m_prim.Orientation = m_rot; + } + } +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs new file mode 100644 index 0000000..61be56d --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs @@ -0,0 +1,68 @@ +/* + * 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 copyrightD + * 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.Region.Physics.Manager; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public class BSPlugin : IPhysicsPlugin +{ + //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private BSScene _mScene; + + public BSPlugin() + { + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene(String sceneIdentifier) + { + if (_mScene == null) + { + _mScene = new BSScene(sceneIdentifier); + } + return (_mScene); + } + + public string GetName() + { + return ("BulletSim"); + } + + public void Dispose() + { + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs new file mode 100644 index 0000000..82a8803 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -0,0 +1,1192 @@ +/* + * 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 copyrightD + * 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.Reflection; +using System.Collections.Generic; +using System.Xml; +using log4net; +using OMV = OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenSim.Region.Physics.ConvexDecompositionDotNet; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + [Serializable] +public sealed class BSPrim : PhysicsActor +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[BULLETS PRIM]"; + + private IMesh _mesh; + private PrimitiveBaseShape _pbs; + private ShapeData.PhysicsShapeType _shapeType; + private ulong _hullKey; + private List _hulls; + + private BSScene _scene; + private String _avName; + private uint _localID = 0; + + private OMV.Vector3 _size; + private OMV.Vector3 _scale; + private bool _stopped; + private bool _grabbed; + private bool _isSelected; + private bool _isVolumeDetect; + private OMV.Vector3 _position; + private float _mass; + private float _density; + private OMV.Vector3 _force; + private OMV.Vector3 _velocity; + private OMV.Vector3 _torque; + private float _collisionScore; + private OMV.Vector3 _acceleration; + private OMV.Quaternion _orientation; + private int _physicsActorType; + private bool _isPhysical; + private bool _flying; + private float _friction; + private bool _setAlwaysRun; + private bool _throttleUpdates; + private bool _isColliding; + private bool _collidingGround; + private bool _collidingObj; + private bool _floatOnWater; + private OMV.Vector3 _rotationalVelocity; + private bool _kinematic; + private float _buoyancy; + private OMV.Vector3 _angularVelocity; + + private List _childrenPrims; + private BSPrim _parentPrim; + + private int _subscribedEventsMs = 0; + private int _lastCollisionTime = 0; + long _collidingStep; + long _collidingGroundStep; + + private BSDynamics _vehicle; + + private OMV.Vector3 _PIDTarget; + private bool _usePID; + private float _PIDTau; + private bool _useHoverPID; + private float _PIDHoverHeight; + private PIDHoverType _PIDHoverType; + private float _PIDHoverTao; + + public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, + OMV.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical) + { + // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); + _localID = localID; + _avName = primName; + _scene = parent_scene; + _position = pos; + _size = size; + _scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type + _orientation = rotation; + _buoyancy = 1f; + _velocity = OMV.Vector3.Zero; + _angularVelocity = OMV.Vector3.Zero; + _mesh = mesh; + _hullKey = 0; + _pbs = pbs; + _isPhysical = pisPhysical; + _isVolumeDetect = false; + _subscribedEventsMs = 0; + _friction = _scene.DefaultFriction; // TODO: compute based on object material + _density = _scene.DefaultDensity; // TODO: compute based on object material + _parentPrim = null; // not a child or a parent + _vehicle = new BSDynamics(this); // add vehicleness + _childrenPrims = new List(); + if (_isPhysical) + _mass = CalculateMass(); + else + _mass = 0f; + // do the actual object creation at taint time + _scene.TaintedObject(delegate() + { + CreateGeom(); + CreateObject(); + }); + } + + // called when this prim is being destroyed and we should free all the resources + public void Destroy() + { + // m_log.DebugFormat("{0}: Destroy", LogHeader); + // Undo any vehicle properties + _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); + _scene.RemoveVehiclePrim(this); // just to make sure + _scene.TaintedObject(delegate() + { + BulletSimAPI.DestroyObject(_scene.WorldID, _localID); + }); + } + + public override bool Stopped { + get { return _stopped; } + } + public override OMV.Vector3 Size { + get { return _size; } + set { + _size = value; + _scene.TaintedObject(delegate() + { + if (_isPhysical) _mass = CalculateMass(); // changing size changes the mass + BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, _mass, _isPhysical); + RecreateGeomAndObject(); + }); + } + } + public override PrimitiveBaseShape Shape { + set { + _pbs = value; + _scene.TaintedObject(delegate() + { + if (_isPhysical) _mass = CalculateMass(); // changing the shape changes the mass + RecreateGeomAndObject(); + }); + } + } + public override uint LocalID { + set { _localID = value; } + get { return _localID; } + } + public override bool Grabbed { + set { _grabbed = value; + } + } + public override bool Selected { + set { + _isSelected = value; + _scene.TaintedObject(delegate() + { + SetObjectDynamic(); + }); + } + } + public override void CrossingFailure() { return; } + + // link me to the specified parent + public override void link(PhysicsActor obj) { + BSPrim parent = (BSPrim)obj; + // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); + // TODO: decide if this parent checking needs to happen at taint time + if (_parentPrim == null) + { + if (parent != null) + { + // I don't have a parent so I am joining a linkset + parent.AddChildToLinkset(this); + } + } + else + { + // I already have a parent, is parenting changing? + if (parent != _parentPrim) + { + if (parent == null) + { + // we are being removed from a linkset + _parentPrim.RemoveChildFromLinkset(this); + } + else + { + // asking to reparent a prim should not happen + m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader); + } + } + } + return; + } + + // delink me from my linkset + public override void delink() { + // TODO: decide if this parent checking needs to happen at taint time + // Race condition here: if link() and delink() in same simulation tick, the delink will not happen + // m_log.DebugFormat("{0}: delink {1}/{2}", LogHeader, _avName, _localID); + if (_parentPrim != null) + { + _parentPrim.RemoveChildFromLinkset(this); + } + return; + } + + public void AddChildToLinkset(BSPrim pchild) + { + BSPrim child = pchild; + _scene.TaintedObject(delegate() + { + if (!_childrenPrims.Contains(child)) + { + _childrenPrims.Add(child); + child.ParentPrim = this; // the child has gained a parent + RecreateGeomAndObject(); // rebuild my shape with the new child added + } + }); + return; + } + + public void RemoveChildFromLinkset(BSPrim pchild) + { + BSPrim child = pchild; + _scene.TaintedObject(delegate() + { + if (_childrenPrims.Contains(child)) + { + _childrenPrims.Remove(child); + child.ParentPrim = null; // the child has lost its parent + RecreateGeomAndObject(); // rebuild my shape with the child removed + } + else + { + m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset"); + } + }); + return; + } + + public BSPrim ParentPrim + { + set { _parentPrim = value; } + } + + public ulong HullKey + { + get { return _hullKey; } + } + + // return true if we are the root of a linkset (there are children to manage) + public bool IsRootOfLinkset + { + get { return (_parentPrim == null && _childrenPrims.Count != 0); } + } + + public override void LockAngularMotion(OMV.Vector3 axis) { return; } + + public override OMV.Vector3 Position { + get { + // don't do the following GetObjectPosition because this function is called a zillion times + // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + return _position; + } + set { + _position = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); + // m_log.DebugFormat("{0}: setPosition: id={1}, position={2}", LogHeader, _localID, _position); + }); + } + } + public override float Mass { + get { return _mass; } + } + public override OMV.Vector3 Force { + get { return _force; } + set { + _force = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); + }); + } + } + + public override int VehicleType { + get { + return (int)_vehicle.Type; // if we are a vehicle, return that type + } + set { + Vehicle type = (Vehicle)value; + _vehicle.ProcessTypeChange(type); + _scene.TaintedObject(delegate() + { + if (type == Vehicle.TYPE_NONE) + { + _scene.RemoveVehiclePrim(this); + } + else + { + // make it so the scene will call us each tick to do vehicle things + _scene.AddVehiclePrim(this); + } + return; + }); + } + } + public override void VehicleFloatParam(int param, float value) + { + _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); + } + public override void VehicleVectorParam(int param, OMV.Vector3 value) + { + _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); + } + public override void VehicleRotationParam(int param, OMV.Quaternion rotation) + { + _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + } + public override void VehicleFlags(int param, bool remove) + { + _vehicle.ProcessVehicleFlags(param, remove); + } + // Called each simulation step to advance vehicle characteristics + public void StepVehicle(float timeStep) + { + _vehicle.Step(timeStep, _scene); + } + + // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more + public override void SetVolumeDetect(int param) { + bool newValue = (param != 0); + if (_isVolumeDetect != newValue) + { + _isVolumeDetect = newValue; + _scene.TaintedObject(delegate() + { + SetObjectDynamic(); + }); + } + return; + } + + public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } + public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } + public override OMV.Vector3 Velocity { + get { return _velocity; } + set { _velocity = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); + }); + } + } + public OMV.Vector3 AngularVelocity + { + get { return _angularVelocity; } + set + { + _angularVelocity = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _angularVelocity); + }); + } + } + public override OMV.Vector3 Torque { + get { return _torque; } + set { _torque = value; + } + } + public override float CollisionScore { + get { return _collisionScore; } + set { _collisionScore = value; + } + } + public override OMV.Vector3 Acceleration { + get { return _acceleration; } + } + public override OMV.Quaternion Orientation { + get { return _orientation; } + set { + _orientation = value; + _scene.TaintedObject(delegate() + { + // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); + // m_log.DebugFormat("{0}: set orientation: {1}", LogHeader, _orientation); + }); + } + } + public override int PhysicsActorType { + get { return _physicsActorType; } + set { _physicsActorType = value; + } + } + public override bool IsPhysical { + get { return _isPhysical; } + set { + _isPhysical = value; + _scene.TaintedObject(delegate() + { + SetObjectDynamic(); + }); + } + } + + // An object is static (does not move) if selected or not physical + private bool IsStatic + { + get { return _isSelected || !IsPhysical; } + } + + // An object is solid if it's not phantom and if it's not doing VolumeDetect + private bool IsSolid + { + get { return !IsPhantom && !_isVolumeDetect; } + } + + // make gravity work if the object is physical and not selected + // no locking here because only called when it is safe + private void SetObjectDynamic() + { + // non-physical things work best with a mass of zero + _mass = IsStatic ? 0f : CalculateMass(); + BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); + // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}, mass={4}", LogHeader, _localID, IsStatic, IsSolid, _mass); + } + + // prims don't fly + public override bool Flying { + get { return _flying; } + set { _flying = value; } + } + public override bool SetAlwaysRun { + get { return _setAlwaysRun; } + set { _setAlwaysRun = value; } + } + public override bool ThrottleUpdates { + get { return _throttleUpdates; } + set { _throttleUpdates = value; } + } + public override bool IsColliding { + get { return (_collidingStep == _scene.SimulationStep); } + set { _isColliding = value; } + } + public override bool CollidingGround { + get { return (_collidingGroundStep == _scene.SimulationStep); } + set { _collidingGround = value; } + } + public override bool CollidingObj { + get { return _collidingObj; } + set { _collidingObj = value; } + } + public bool IsPhantom { + get { + // SceneObjectPart removes phantom objects from the physics scene + // so, although we could implement touching and such, we never + // are invoked as a phantom object + return false; + } + } + public override bool FloatOnWater { + set { _floatOnWater = value; } + } + public override OMV.Vector3 RotationalVelocity { + get { return _rotationalVelocity; } + set { _rotationalVelocity = value; + // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); + } + } + public override bool Kinematic { + get { return _kinematic; } + set { _kinematic = value; + // m_log.DebugFormat("{0}: Kinematic={1}", LogHeader, _kinematic); + } + } + public override float Buoyancy { + get { return _buoyancy; } + set { _buoyancy = value; + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); + }); + } + } + + // Used for MoveTo + public override OMV.Vector3 PIDTarget { + set { _PIDTarget = value; } + } + public override bool PIDActive { + set { _usePID = value; } + } + public override float PIDTau { + set { _PIDTau = value; } + } + + // Used for llSetHoverHeight and maybe vehicle height + // Hover Height will override MoveTo target's Z + public override bool PIDHoverActive { + set { _useHoverPID = value; } + } + public override float PIDHoverHeight { + set { _PIDHoverHeight = value; } + } + public override PIDHoverType PIDHoverType { + set { _PIDHoverType = value; } + } + public override float PIDHoverTau { + set { _PIDHoverTao = value; } + } + + // For RotLookAt + public override OMV.Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + + public override void AddForce(OMV.Vector3 force, bool pushforce) { + if (force.IsFinite()) + { + _force.X += force.X; + _force.Y += force.Y; + _force.Z += force.Z; + } + else + { + m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); + } + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); + }); + } + + public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { + // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); + } + public override void SetMomentum(OMV.Vector3 momentum) { + } + public override void SubscribeEvents(int ms) { + _subscribedEventsMs = ms; + _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen + } + public override void UnSubscribeEvents() { + _subscribedEventsMs = 0; + } + public override bool SubscribedEvents() { + return (_subscribedEventsMs > 0); + } + + #region Mass Calculation + + private float CalculateMass() + { + float volume = _size.X * _size.Y * _size.Z; // default + float tmp; + + float returnMass = 0; + float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; + float hollowVolume = hollowAmount * hollowAmount; + + switch (_pbs.ProfileShape) + { + case ProfileShape.Square: + // default box + + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + if (hollowAmount > 0.0) + { + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; + + case HollowShape.Circle: + + hollowVolume *= 0.78539816339f; + break; + + case HollowShape.Triangle: + + hollowVolume *= (0.5f * .5f); + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + //a tube + + volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); + tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY); + volume -= volume*tmp*tmp; + + if (hollowAmount > 0.0) + { + hollowVolume *= hollowAmount; + + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; + + case HollowShape.Circle: + hollowVolume *= 0.78539816339f;; + break; + + case HollowShape.Triangle: + hollowVolume *= 0.5f * 0.5f; + break; + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + break; + + case ProfileShape.Circle: + + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + volume *= 0.78539816339f; // elipse base + + if (hollowAmount > 0.0) + { + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; + + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); + volume *= (1.0f - tmp * tmp); + + if (hollowAmount > 0.0) + { + + // calculate the hollow volume by it's shape compared to the prim shape + hollowVolume *= hollowAmount; + + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; + + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + break; + + case ProfileShape.HalfCircle: + if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.52359877559829887307710723054658f; + } + break; + + case ProfileShape.EquilateralTriangle: + + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + volume *= 0.32475953f; + + if (hollowAmount > 0.0) + { + + // calculate the hollow volume by it's shape compared to the prim shape + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; + + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.32475953f; + volume *= 0.01f * (float)(200 - _pbs.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); + volume *= (1.0f - tmp * tmp); + + if (hollowAmount > 0.0) + { + + hollowVolume *= hollowAmount; + + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; + + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; + + case HollowShape.Circle: + + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + break; + + default: + break; + } + + + + float taperX1; + float taperY1; + float taperX; + float taperY; + float pathBegin; + float pathEnd; + float profileBegin; + float profileEnd; + + if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) + { + taperX1 = _pbs.PathScaleX * 0.01f; + if (taperX1 > 1.0f) + taperX1 = 2.0f - taperX1; + taperX = 1.0f - taperX1; + + taperY1 = _pbs.PathScaleY * 0.01f; + if (taperY1 > 1.0f) + taperY1 = 2.0f - taperY1; + taperY = 1.0f - taperY1; + } + else + { + taperX = _pbs.PathTaperX * 0.01f; + if (taperX < 0.0f) + taperX = -taperX; + taperX1 = 1.0f - taperX; + + taperY = _pbs.PathTaperY * 0.01f; + if (taperY < 0.0f) + taperY = -taperY; + taperY1 = 1.0f - taperY; + + } + + + volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); + + pathBegin = (float)_pbs.PathBegin * 2.0e-5f; + pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; + volume *= (pathEnd - pathBegin); + + // this is crude aproximation + profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; + profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; + volume *= (profileEnd - profileBegin); + + returnMass = _density * volume; + + if (returnMass <= 0) + returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. + + if (IsRootOfLinkset) + { + foreach (BSPrim prim in _childrenPrims) + { + returnMass += prim.CalculateMass(); + } + } + + if (returnMass > _scene.maximumMassObject) + returnMass = _scene.maximumMassObject; + return returnMass; + }// end CalculateMass + #endregion Mass Calculation + + // Create the geometry information in Bullet for later use + // No locking here because this is done when we know physics is not simulating + private void CreateGeom() + { + if (_mesh == null) + { + // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. + if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) + { + // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to sphere of size {1}", LogHeader, _size); + _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; + // Bullet native objects are scaled by the Bullet engine so pass the size in + _scale = _size; + } + } + else + { + // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to box of size {1}", LogHeader, _size); + _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; + _scale = _size; + } + } + else + { + if (_hullKey != 0) + { + // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); + BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); + _hullKey = 0; + _hulls.Clear(); + } + + int[] indices = _mesh.getIndexListAsInt(); + List vertices = _mesh.getVertexList(); + + //format conversion from IMesh format to DecompDesc format + List convIndices = new List(); + List convVertices = new List(); + for (int ii = 0; ii < indices.GetLength(0); ii++) + { + convIndices.Add(indices[ii]); + } + foreach (OMV.Vector3 vv in vertices) + { + convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); + } + + // setup and do convex hull conversion + _hulls = new List(); + DecompDesc dcomp = new DecompDesc(); + dcomp.mIndices = convIndices; + dcomp.mVertices = convVertices; + ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); + // create the hull into the _hulls variable + convexBuilder.process(dcomp); + + // Convert the vertices and indices for passing to unmanaged + // The hull information is passed as a large floating point array. + // The format is: + // convHulls[0] = number of hulls + // convHulls[1] = number of vertices in first hull + // convHulls[2] = hull centroid X coordinate + // convHulls[3] = hull centroid Y coordinate + // convHulls[4] = hull centroid Z coordinate + // convHulls[5] = first hull vertex X + // convHulls[6] = first hull vertex Y + // convHulls[7] = first hull vertex Z + // convHulls[8] = second hull vertex X + // ... + // convHulls[n] = number of vertices in second hull + // convHulls[n+1] = second hull centroid X coordinate + // ... + // + // TODO: is is very inefficient. Someday change the convex hull generator to return + // data structures that do not need to be converted in order to pass to Bullet. + // And maybe put the values directly into pinned memory rather than marshaling. + int hullCount = _hulls.Count; + int totalVertices = 1; // include one for the count of the hulls + foreach (ConvexResult cr in _hulls) + { + totalVertices += 4; // add four for the vertex count and centroid + totalVertices += cr.HullIndices.Count * 3; // we pass just triangles + } + float[] convHulls = new float[totalVertices]; + + convHulls[0] = (float)hullCount; + int jj = 1; + foreach (ConvexResult cr in _hulls) + { + // copy vertices for index access + float3[] verts = new float3[cr.HullVertices.Count]; + int kk = 0; + foreach (float3 ff in cr.HullVertices) + { + verts[kk++] = ff; + } + + // add to the array one hull's worth of data + convHulls[jj++] = cr.HullIndices.Count; + convHulls[jj++] = 0f; // centroid x,y,z + convHulls[jj++] = 0f; + convHulls[jj++] = 0f; + foreach (int ind in cr.HullIndices) + { + convHulls[jj++] = verts[ind].x; + convHulls[jj++] = verts[ind].y; + convHulls[jj++] = verts[ind].z; + } + } + + // create the hull definition in Bullet + _hullKey = (ulong)_pbs.GetHashCode(); + // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid= {1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); + BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); + _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; + // meshes are already scaled by the meshmerizer + _scale = new OMV.Vector3(1f, 1f, 1f); + } + return; + } + + private void HullReturn(ConvexResult result) + { + _hulls.Add(result); + return; + } + + // Create an object in Bullet + // No locking here because this is done when the physics engine is not simulating + private void CreateObject() + { + if (IsRootOfLinkset) + { + // Create a linkset around this object + /* + * NOTE: the original way of creating a linkset was to create a compound hull in the + * root which consisted of the hulls of all the children. This didn't work well because + * OpenSimulator needs updates and collisions for all the children and the physics + * engine didn't create events for the children when the root hull was moved. + * This code creates the compound hull. + // If I am the root prim of a linkset, replace my physical shape with all the + // pieces of the children. + // All of the children should have called CreateGeom so they have a hull + // in the physics engine already. Here we pull together all of those hulls + // into one shape. + int totalPrimsInLinkset = _childrenPrims.Count + 1; + // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset); + ShapeData[] shapes = new ShapeData[totalPrimsInLinkset]; + FillShapeInfo(out shapes[0]); + int ii = 1; + foreach (BSPrim prim in _childrenPrims) + { + // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID); + prim.FillShapeInfo(out shapes[ii]); + ii++; + } + BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes); + */ + // Create the linkset by putting constraints between the objects of the set so they cannot move + // relative to each other. + // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); + + // remove any constraints that might be in place + foreach (BSPrim prim in _childrenPrims) + { + BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID); + } + // create constraints between the root prim and each of the children + foreach (BSPrim prim in _childrenPrims) + { + // this is a constraint that allows no freedom of movement between the two objects + // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 + BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, OMV.Vector3.Zero, OMV.Vector3.Zero, + OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero); + } + } + else + { + // simple object + // m_log.DebugFormat("{0}: CreateObject. ID={1}", LogHeader, LocalID); + ShapeData shape; + FillShapeInfo(out shape); + BulletSimAPI.CreateObject(_scene.WorldID, shape); + } + } + + // Copy prim's info into the BulletSim shape description structure + public void FillShapeInfo(out ShapeData shape) + { + shape.ID = _localID; + shape.Type = _shapeType; + shape.Position = _position; + shape.Rotation = _orientation; + shape.Velocity = _velocity; + shape.Scale = _scale; + shape.Mass = _isPhysical ? _mass : 0f; + shape.Buoyancy = _buoyancy; + shape.MeshKey = _hullKey; + shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; + shape.Friction = _friction; + shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; + } + + // Rebuild the geometry and object. + // This is called when the shape changes so we need to recreate the mesh/hull. + // No locking here because this is done when the physics engine is not simulating + private void RecreateGeomAndObject() + { + if (_hullKey != 0) + { + // if a hull already exists, delete the old one + BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); + _hullKey = 0; + } + // If this object is complex or we are the root of a linkset, build a mesh. + // The root of a linkset must be a mesh so we can create the linked compound object. + if (_scene.NeedsMeshing(_pbs) || IsRootOfLinkset ) + { + // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); + _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.meshLOD, _isPhysical); + } + else + { + // it's a BulletSim native shape. + _mesh = null; + } + CreateGeom(); // create the geometry for this prim + CreateObject(); + return; + } + + // The physics engine says that properties have updated. Update same and inform + // the world that things have changed. + // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() + private int UpPropPosition = 1 << 0; + private int UpPropRotation = 1 << 1; + private int UpPropVelocity = 1 << 2; + private int UpPropAcceleration = 1 << 3; + private int UpPropAngularVel = 1 << 4; + + public void UpdateProperties(EntityProperties entprop) + { + int changed = 0; + // assign to the local variables so the normal set action does not happen + if (_position != entprop.Position) + { + _position = entprop.Position; + // m_log.DebugFormat("{0}: UpdateProperties: position = {1}", LogHeader, _position); + changed |= UpPropPosition; + } + if (_orientation != entprop.Rotation) + { + _orientation = entprop.Rotation; + // m_log.DebugFormat("{0}: UpdateProperties: rotation = {1}", LogHeader, _orientation); + changed |= UpPropRotation; + } + if (_velocity != entprop.Velocity) + { + _velocity = entprop.Velocity; + // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity); + changed |= UpPropVelocity; + } + if (_acceleration != entprop.Acceleration) + { + _acceleration = entprop.Acceleration; + // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration); + changed |= UpPropAcceleration; + } + if (_rotationalVelocity != entprop.AngularVelocity) + { + _rotationalVelocity = entprop.AngularVelocity; + // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); + changed |= UpPropAngularVel; + } + if (changed != 0) + { + // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); + base.RequestPhysicsterseUpdate(); + } + } + + // I've collided with something + public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + { + // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); + // The following makes IsColliding() and IsCollidingGround() work + _collidingStep = _scene.SimulationStep; + if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) + { + _collidingGroundStep = _scene.SimulationStep; + } + + if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events + // throttle the collisions to the number of milliseconds specified in the subscription + int nowTime = Util.EnvironmentTickCount(); + if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; + _lastCollisionTime = nowTime; + + // create the event for the collision + Dictionary contactPoints = new Dictionary(); + contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints); + base.SendCollisionUpdate(args); + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs new file mode 100644 index 0000000..beffd21 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -0,0 +1,553 @@ +/* + * 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 copyrightD + * 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 System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using Nini.Config; +using log4net; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenMetaverse; +using OpenSim.Region.Framework; + +// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) +// Fix folding up feet +// Fix terrain. Only flat terrain works. Terrain with shape is oriented wrong? Origined wrong? +// Parameterize BulletSim. Pass a structure of parameters to the C++ code. Capsule size, friction, ... +// Shift drag duplication of objects does not work +// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) +// Test sculpties +// Compute physics FPS reasonably +// Based on material, set density and friction +// More efficient memory usage in passing hull information from BSPrim to BulletSim +// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? +// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) +// At the moment, physical and phantom causes object to drop through the terrain +// Should prim.link() and prim.delink() membership checking happen at taint time? +// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once +// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect +// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions) +// Implement LockAngularMotion +// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) +// Built Galton board (lots of MoveTo's) and some slats were not positioned correctly (mistakes scattered) +// No mistakes with ODE. Shape creation race condition? +// Does NeedsMeshing() really need to exclude all the different shapes? +// +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public class BSScene : PhysicsScene +{ + private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[BULLETS SCENE]"; + + private Dictionary m_avatars = new Dictionary(); + private Dictionary m_prims = new Dictionary(); + private List m_vehicles = new List(); + private float[] m_heightMap; + private float m_waterLevel; + private uint m_worldID; + public uint WorldID { get { return m_worldID; } } + + public IMesher mesher; + public int meshLOD = 32; + + private int m_maxSubSteps = 10; + private float m_fixedTimeStep = 1f / 60f; + private long m_simulationStep = 0; + public long SimulationStep { get { return m_simulationStep; } } + + private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed + private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes + public float maximumMassObject = 10000.01f; + + public const uint TERRAIN_ID = 0; + public const uint GROUNDPLANE_ID = 1; + + public float DefaultFriction = 0.70f; + public float DefaultDensity = 10.000006836f; // Aluminum g/cm3; TODO: compute based on object material + public Vector3 DefaultGravity = new Vector3(0, 0, -9.80665f); + + public delegate void TaintCallback(); + private List _taintedObjects; + private Object _taintLock = new Object(); + + private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; + + public BSScene(string identifier) + { + } + + public override void Initialise(IMesher meshmerizer, IConfigSource config) + { + if (config != null) + { + IConfig pConfig = config.Configs["BulletSim"]; + if (pConfig != null) + { + DefaultFriction = pConfig.GetFloat("Friction", DefaultFriction); + DefaultDensity = pConfig.GetFloat("Density", DefaultDensity); + // TODO: a lot more parameters that are passed to BulletSim + } + } + // if Debug, enable logging from the unmanaged code + if (m_log.IsDebugEnabled) + { + m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); + debugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); + BulletSimAPI.SetDebugLogCallback(debugLogCallbackHandle); + } + + _meshSculptedPrim = true; // mesh sculpted prims + _forceSimplePrimMeshing = false; // use complex meshing if called for + + _taintedObjects = new List(); + + mesher = meshmerizer; + // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); + m_worldID = BulletSimAPI.Initialize(new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f)); + } + + // Called directly from unmanaged code so don't do much + private void BulletLogger(string msg) + { + m_log.Debug("[BULLETS UNMANAGED]:" + msg); + } + + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) + { + m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); + return null; + } + + public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) + { + // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); + BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); + lock (m_avatars) m_avatars.Add(localID, actor); + return actor; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader); + if (actor is BSCharacter) + { + ((BSCharacter)actor).Destroy(); + } + try + { + lock (m_avatars) m_avatars.Remove(actor.LocalID); + } + catch (Exception e) + { + m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e); + } + } + + public override void RemovePrim(PhysicsActor prim) + { + // m_log.DebugFormat("{0}: RemovePrim", LogHeader); + if (prim is BSPrim) + { + ((BSPrim)prim).Destroy(); + } + try + { + lock (m_prims) m_prims.Remove(prim.LocalID); + } + catch (Exception e) + { + m_log.WarnFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e); + } + } + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation) // deprecated + { + return null; + } + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical) + { + m_log.ErrorFormat("{0}: CALL TO AddPrimShape in BSScene. NOT IMPLEMENTED", LogHeader); + return null; + } + + public override PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical) + { + // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); + IMesh mesh = null; + if (NeedsMeshing(pbs)) + { + // if the prim is complex, create the mesh for it. + // If simple (box or sphere) leave 'mesh' null and physics will do a native shape. + mesh = mesher.CreateMesh(primName, pbs, size, this.meshLOD, isPhysical); + } + BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, mesh, pbs, isPhysical); + lock (m_prims) m_prims.Add(localID, prim); + return prim; + } + + // This is a call from the simulator saying that some physical property has been updated. + // The BulletS driver senses the changing of relevant properties so this taint + // information call is not needed. + public override void AddPhysicsActorTaint(PhysicsActor prim) { } + + // Simulate one timestep + public override float Simulate(float timeStep) + { + int updatedEntityCount; + IntPtr updatedEntitiesPtr; + IntPtr[] updatedEntities; + int collidersCount; + IntPtr collidersPtr; + int[] colliders; // should be uint but Marshal.Copy does not have that overload + + // update the prim states while we know the physics engine is not busy + ProcessTaints(); + + // Some of the prims operate with special vehicle properties + ProcessVehicles(timeStep); + ProcessTaints(); // the vehicles might have added taints + + // step the physical world one interval + m_simulationStep++; + int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, + out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); + + // if there were collisions, they show up here + if (collidersCount > 0) + { + colliders = new int[collidersCount]; + Marshal.Copy(collidersPtr, colliders, 0, collidersCount); + for (int ii = 0; ii < collidersCount; ii+=2) + { + uint cA = (uint)colliders[ii]; + uint cB = (uint)colliders[ii+1]; + SendCollision(cA, cB); + SendCollision(cB, cA); + } + } + + // if any of the objects had updated properties, they are returned in the updatedEntity structure + // TODO: figure out how to pass all of the EntityProperties structures in one marshal call. + if (updatedEntityCount > 0) + { + updatedEntities = new IntPtr[updatedEntityCount]; + // fetch all the pointers to all the EntityProperties structures for these updates + Marshal.Copy(updatedEntitiesPtr, updatedEntities, 0, updatedEntityCount); + for (int ii = 0; ii < updatedEntityCount; ii++) + { + IntPtr updatePointer = updatedEntities[ii]; + EntityProperties entprop = (EntityProperties)Marshal.PtrToStructure(updatePointer, typeof(EntityProperties)); + // m_log.DebugFormat("{0}: entprop: id={1}, pos={2}", LogHeader, entprop.ID, entprop.Position); + BSCharacter actor; + if (m_avatars.TryGetValue(entprop.ID, out actor)) + { + actor.UpdateProperties(entprop); + continue; + } + BSPrim prim; + if (m_prims.TryGetValue(entprop.ID, out prim)) + { + prim.UpdateProperties(entprop); + } + } + } + + // fps calculation wrong. This calculation returns about 1 in normal operation. + return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; + } + + // Something has collided + private void SendCollision(uint localID, uint collidingWith) + { + if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) + { + // we never send collisions to the terrain + return; + } + + ActorTypes type = ActorTypes.Prim; + if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) + type = ActorTypes.Ground; + else if (m_avatars.ContainsKey(collidingWith)) + type = ActorTypes.Agent; + + BSPrim prim; + if (m_prims.TryGetValue(localID, out prim)) { + prim.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f); + return; + } + BSCharacter actor; + if (m_avatars.TryGetValue(localID, out actor)) { + actor.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f); + return; + } + return; + } + + public override void GetResults() { } + + public override void SetTerrain(float[] heightMap) { + m_log.DebugFormat("{0}: SetTerrain", LogHeader); + m_heightMap = heightMap; + this.TaintedObject(delegate() + { + BulletSimAPI.SetHeightmap(m_worldID, m_heightMap); + }); + } + + public float GetTerrainHeightAtXY(float tX, float tY) + { + return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)]; + } + + public override void SetWaterLevel(float baseheight) + { + m_waterLevel = baseheight; + } + public float GetWaterLevel() + { + return m_waterLevel; + } + + public override void DeleteTerrain() + { + m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); + } + + public override void Dispose() + { + m_log.DebugFormat("{0}: Dispose()", LogHeader); + } + + public override Dictionary GetTopColliders() + { + return new Dictionary(); + } + + public override bool IsThreaded { get { return false; } } + + /// + /// Routine to figure out if we need to mesh this prim with our mesher + /// + /// + /// true if the prim needs meshing + public bool NeedsMeshing(PrimitiveBaseShape pbs) + { + // most of this is redundant now as the mesher will return null if it cant mesh a prim + // but we still need to check for sculptie meshing being enabled so this is the most + // convenient place to do it for now... + + // int iPropertiesNotSupportedDefault = 0; + + if (pbs.SculptEntry && !_meshSculptedPrim) + { + // m_log.DebugFormat("{0}: NeedsMeshing: scultpy mesh", LogHeader); + return false; + } + + // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet + // can use an internal representation for the prim + if (!_forceSimplePrimMeshing) + { + // m_log.DebugFormat("{0}: NeedsMeshing: simple mesh: profshape={1}, curve={2}", LogHeader, pbs.ProfileShape, pbs.PathCurve); + if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) + || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 + && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) + { + + if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 + && pbs.ProfileHollow == 0 + && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 + && pbs.PathBegin == 0 && pbs.PathEnd == 0 + && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 + && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 + && pbs.PathShearX == 0 && pbs.PathShearY == 0) + { + return false; + } + } + } + + /* TODO: verify that the mesher will now do all these shapes + if (pbs.ProfileHollow != 0) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathBegin != 0) || pbs.PathEnd != 0) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) + iPropertiesNotSupportedDefault++; + + if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) + iPropertiesNotSupportedDefault++; + + if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) + iPropertiesNotSupportedDefault++; + + if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) + iPropertiesNotSupportedDefault++; + + if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1) + iPropertiesNotSupportedDefault++; + + // test for torus + if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square) + { + if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + { + if (pbs.PathCurve == (byte)Extrusion.Straight) + { + iPropertiesNotSupportedDefault++; + } + // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits + else if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + { + if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + { + if (pbs.PathCurve == (byte)Extrusion.Straight) + { + iPropertiesNotSupportedDefault++; + } + else if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + if (iPropertiesNotSupportedDefault == 0) + { + return false; + } + */ + return true; + } + + // The calls to the PhysicsActors can't directly call into the physics engine + // because it might be busy. We we delay changes to a known time. + // We rely on C#'s closure to save and restore the context for the delegate. + public void TaintedObject(TaintCallback callback) + { + lock (_taintLock) + _taintedObjects.Add(callback); + return; + } + + // When someone tries to change a property on a BSPrim or BSCharacter, the object queues + // a callback into itself to do the actual property change. That callback is called + // here just before the physics engine is called to step the simulation. + public void ProcessTaints() + { + if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process + { + // swizzle a new list into the list location so we can process what's there + List oldList; + lock (_taintLock) + { + oldList = _taintedObjects; + _taintedObjects = new List(); + } + + foreach (TaintCallback callback in oldList) + { + try + { + callback(); + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e); + } + } + oldList.Clear(); + } + } + + #region Vehicles + // Make so the scene will call this prim for vehicle actions each tick. + // Safe to call if prim is already in the vehicle list. + public void AddVehiclePrim(BSPrim vehicle) + { + lock (m_vehicles) + { + if (!m_vehicles.Contains(vehicle)) + { + m_vehicles.Add(vehicle); + } + } + } + + // Remove a prim from our list of vehicles. + // Safe to call if the prim is not in the vehicle list. + public void RemoveVehiclePrim(BSPrim vehicle) + { + lock (m_vehicles) + { + if (m_vehicles.Contains(vehicle)) + { + m_vehicles.Remove(vehicle); + } + } + } + + // Some prims have extra vehicle actions + // no locking because only called when physics engine is not busy + private void ProcessVehicles(float timeStep) + { + foreach (BSPrim prim in m_vehicles) + { + prim.StepVehicle(timeStep); + } + } + #endregion Vehicles +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs new file mode 100644 index 0000000..b2bc0d7 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -0,0 +1,186 @@ +/* + * 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 copyrightD + * 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.Runtime.InteropServices; +using System.Security; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin { + +public struct ConvexHull +{ + Vector3 Offset; + int VertexCount; + Vector3[] Vertices; +} +public struct ShapeData +{ + public enum PhysicsShapeType + { + SHAPE_AVATAR = 0, + SHAPE_BOX = 1, + SHAPE_CONE = 2, + SHAPE_CYLINDER = 3, + SHAPE_SPHERE = 4, + SHAPE_HULL = 5 + }; + public const int numericTrue = 1; + public const int numericFalse = 0; + public uint ID; + public PhysicsShapeType Type; + public Vector3 Position; + public Quaternion Rotation; + public Vector3 Velocity; + public Vector3 Scale; + public float Mass; + public float Buoyancy; + public System.UInt64 MeshKey; + public int Collidable; + public float Friction; + public int Static; // true if a static object. Otherwise gravity, etc. + // note that bools are passed as ints since bool size changes by language +} +public struct SweepHit +{ + public uint ID; + public float Fraction; + public Vector3 Normal; + public Vector3 Point; +} +public struct RaycastHit +{ + public uint ID; + public float Fraction; + public Vector3 Normal; +} + +public struct EntityProperties +{ + public uint ID; + public Vector3 Position; + public Quaternion Rotation; + public Vector3 Velocity; + public Vector3 Acceleration; + public Vector3 AngularVelocity; +} + +static class BulletSimAPI { + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern uint Initialize(Vector3 maxPosition); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Shutdown(uint worldID); + + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool CreateHull(uint worldID, System.UInt64 meshKey, int hullCount, + [MarshalAs(UnmanagedType.LPArray)] float[] hulls + ); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DestroyHull(uint worldID, System.UInt64 meshKey); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool CreateObject(uint worldID, ShapeData shapeData); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void AddConstraint(uint worldID, uint id1, uint id2, + Vector3 frame1, Vector3 frame2, Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetObjectPosition(uint WorldID, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectTranslation(uint worldID, uint id, Vector3 position, Quaternion rotation); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectVelocity(uint worldID, uint id, Vector3 velocity); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectScaleMass(uint worldID, uint id, Vector3 scale, float mass, bool isDynamic); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectCollidable(uint worldID, uint id, bool phantom); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectDynamic(uint worldID, uint id, bool isDynamic, float mass); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectGhost(uint worldID, uint id, bool ghostly); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectProperties(uint worldID, uint id, bool isStatic, bool isSolid, bool genCollisions, float mass); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetObjectBuoyancy(uint worldID, uint id, float buoyancy); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool HasObject(uint worldID, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DestroyObject(uint worldID, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vector3 to); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); + +// Log a debug message +[UnmanagedFunctionPointer(CallingConvention.Cdecl)] +public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetDebugLogCallback(DebugLogCallback callback); +} +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs new file mode 100644 index 0000000..4d84c44 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs @@ -0,0 +1,341 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class Wpoint + { + public float3 mPoint; + public float mWeight; + + public Wpoint(float3 p, float w) + { + mPoint = p; + mWeight = w; + } + } + + public class CTri + { + private const int WSCALE = 4; + + public float3 mP1; + public float3 mP2; + public float3 mP3; + public float3 mNear1; + public float3 mNear2; + public float3 mNear3; + public float3 mNormal; + public float mPlaneD; + public float mConcavity; + public float mC1; + public float mC2; + public float mC3; + public int mI1; + public int mI2; + public int mI3; + public int mProcessed; // already been added... + + public CTri(float3 p1, float3 p2, float3 p3, int i1, int i2, int i3) + { + mProcessed = 0; + mI1 = i1; + mI2 = i2; + mI3 = i3; + + mP1 = new float3(p1); + mP2 = new float3(p2); + mP3 = new float3(p3); + + mNear1 = new float3(); + mNear2 = new float3(); + mNear3 = new float3(); + + mNormal = new float3(); + mPlaneD = mNormal.ComputePlane(mP1, mP2, mP3); + } + + public float Facing(CTri t) + { + return float3.dot(mNormal, t.mNormal); + } + + public bool clip(float3 start, ref float3 end) + { + float3 sect = new float3(); + bool hit = lineIntersectsTriangle(start, end, mP1, mP2, mP3, ref sect); + + if (hit) + end = sect; + return hit; + } + + public bool Concave(float3 p, ref float distance, ref float3 n) + { + n.NearestPointInTriangle(p, mP1, mP2, mP3); + distance = p.Distance(n); + return true; + } + + public void addTri(int[] indices, int i1, int i2, int i3, ref int tcount) + { + indices[tcount * 3 + 0] = i1; + indices[tcount * 3 + 1] = i2; + indices[tcount * 3 + 2] = i3; + tcount++; + } + + public float getVolume() + { + int[] indices = new int[8 * 3]; + + int tcount = 0; + + addTri(indices, 0, 1, 2, ref tcount); + addTri(indices, 3, 4, 5, ref tcount); + + addTri(indices, 0, 3, 4, ref tcount); + addTri(indices, 0, 4, 1, ref tcount); + + addTri(indices, 1, 4, 5, ref tcount); + addTri(indices, 1, 5, 2, ref tcount); + + addTri(indices, 0, 3, 5, ref tcount); + addTri(indices, 0, 5, 2, ref tcount); + + List vertices = new List { mP1, mP2, mP3, mNear1, mNear2, mNear3 }; + List indexList = new List(indices); + + float v = Concavity.computeMeshVolume(vertices, indexList); + return v; + } + + public float raySect(float3 p, float3 dir, ref float3 sect) + { + float4 plane = new float4(); + + plane.x = mNormal.x; + plane.y = mNormal.y; + plane.z = mNormal.z; + plane.w = mPlaneD; + + float3 dest = p + dir * 100000f; + + intersect(p, dest, ref sect, plane); + + return sect.Distance(p); // return the intersection distance + } + + public float planeDistance(float3 p) + { + float4 plane = new float4(); + + plane.x = mNormal.x; + plane.y = mNormal.y; + plane.z = mNormal.z; + plane.w = mPlaneD; + + return DistToPt(p, plane); + } + + public bool samePlane(CTri t) + { + const float THRESH = 0.001f; + float dd = Math.Abs(t.mPlaneD - mPlaneD); + if (dd > THRESH) + return false; + dd = Math.Abs(t.mNormal.x - mNormal.x); + if (dd > THRESH) + return false; + dd = Math.Abs(t.mNormal.y - mNormal.y); + if (dd > THRESH) + return false; + dd = Math.Abs(t.mNormal.z - mNormal.z); + if (dd > THRESH) + return false; + return true; + } + + public bool hasIndex(int i) + { + if (i == mI1 || i == mI2 || i == mI3) + return true; + return false; + } + + public bool sharesEdge(CTri t) + { + bool ret = false; + uint count = 0; + + if (t.hasIndex(mI1)) + count++; + if (t.hasIndex(mI2)) + count++; + if (t.hasIndex(mI3)) + count++; + + if (count >= 2) + ret = true; + + return ret; + } + + public float area() + { + float a = mConcavity * mP1.Area(mP2, mP3); + return a; + } + + public void addWeighted(List list) + { + Wpoint p1 = new Wpoint(mP1, mC1); + Wpoint p2 = new Wpoint(mP2, mC2); + Wpoint p3 = new Wpoint(mP3, mC3); + + float3 d1 = mNear1 - mP1; + float3 d2 = mNear2 - mP2; + float3 d3 = mNear3 - mP3; + + d1 *= WSCALE; + d2 *= WSCALE; + d3 *= WSCALE; + + d1 = d1 + mP1; + d2 = d2 + mP2; + d3 = d3 + mP3; + + Wpoint p4 = new Wpoint(d1, mC1); + Wpoint p5 = new Wpoint(d2, mC2); + Wpoint p6 = new Wpoint(d3, mC3); + + list.Add(p1); + list.Add(p2); + list.Add(p3); + + list.Add(p4); + list.Add(p5); + list.Add(p6); + } + + private static float DistToPt(float3 p, float4 plane) + { + float x = p.x; + float y = p.y; + float z = p.z; + float d = x*plane.x + y*plane.y + z*plane.z + plane.w; + return d; + } + + private static void intersect(float3 p1, float3 p2, ref float3 split, float4 plane) + { + float dp1 = DistToPt(p1, plane); + + float3 dir = new float3(); + dir.x = p2[0] - p1[0]; + dir.y = p2[1] - p1[1]; + dir.z = p2[2] - p1[2]; + + float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2]; + float dot2 = dp1 - plane[3]; + + float t = -(plane[3] + dot2) / dot1; + + split.x = (dir[0] * t) + p1[0]; + split.y = (dir[1] * t) + p1[1]; + split.z = (dir[2] * t) + p1[2]; + } + + private static bool rayIntersectsTriangle(float3 p, float3 d, float3 v0, float3 v1, float3 v2, out float t) + { + t = 0f; + + float3 e1, e2, h, s, q; + float a, f, u, v; + + e1 = v1 - v0; + e2 = v2 - v0; + h = float3.cross(d, e2); + a = float3.dot(e1, h); + + if (a > -0.00001f && a < 0.00001f) + return false; + + f = 1f / a; + s = p - v0; + u = f * float3.dot(s, h); + + if (u < 0.0f || u > 1.0f) + return false; + + q = float3.cross(s, e1); + v = f * float3.dot(d, q); + if (v < 0.0f || u + v > 1.0f) + return false; + + // at this stage we can compute t to find out where + // the intersection point is on the line + t = f * float3.dot(e2, q); + if (t > 0f) // ray intersection + return true; + else // this means that there is a line intersection but not a ray intersection + return false; + } + + private static bool lineIntersectsTriangle(float3 rayStart, float3 rayEnd, float3 p1, float3 p2, float3 p3, ref float3 sect) + { + float3 dir = rayEnd - rayStart; + + float d = (float)Math.Sqrt(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]); + float r = 1.0f / d; + + dir *= r; + + float t; + bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, out t); + + if (ret) + { + if (t > d) + { + sect.x = rayStart.x + dir.x * t; + sect.y = rayStart.y + dir.y * t; + sect.z = rayStart.z + dir.z * t; + } + else + { + ret = false; + } + } + + return ret; + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs new file mode 100644 index 0000000..cc6383a --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs @@ -0,0 +1,233 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public static class Concavity + { + // compute's how 'concave' this object is and returns the total volume of the + // convex hull as well as the volume of the 'concavity' which was found. + public static float computeConcavity(List vertices, List indices, ref float4 plane, ref float volume) + { + float cret = 0f; + volume = 1f; + + HullResult result = new HullResult(); + HullDesc desc = new HullDesc(); + + desc.MaxFaces = 256; + desc.MaxVertices = 256; + desc.SetHullFlag(HullFlag.QF_TRIANGLES); + desc.Vertices = vertices; + + HullError ret = HullUtils.CreateConvexHull(desc, ref result); + + if (ret == HullError.QE_OK) + { + volume = computeMeshVolume2(result.OutputVertices, result.Indices); + + // ok..now..for each triangle on the original mesh.. + // we extrude the points to the nearest point on the hull. + List tris = new List(); + + for (int i = 0; i < result.Indices.Count / 3; i++) + { + int i1 = result.Indices[i * 3 + 0]; + int i2 = result.Indices[i * 3 + 1]; + int i3 = result.Indices[i * 3 + 2]; + + float3 p1 = result.OutputVertices[i1]; + float3 p2 = result.OutputVertices[i2]; + float3 p3 = result.OutputVertices[i3]; + + CTri t = new CTri(p1, p2, p3, i1, i2, i3); + tris.Add(t); + } + + // we have not pre-computed the plane equation for each triangle in the convex hull.. + float totalVolume = 0; + + List ftris = new List(); // 'feature' triangles. + List input_mesh = new List(); + + for (int i = 0; i < indices.Count / 3; i++) + { + int i1 = indices[i * 3 + 0]; + int i2 = indices[i * 3 + 1]; + int i3 = indices[i * 3 + 2]; + + float3 p1 = vertices[i1]; + float3 p2 = vertices[i2]; + float3 p3 = vertices[i3]; + + CTri t = new CTri(p1, p2, p3, i1, i2, i3); + input_mesh.Add(t); + } + + for (int i = 0; i < indices.Count / 3; i++) + { + int i1 = indices[i * 3 + 0]; + int i2 = indices[i * 3 + 1]; + int i3 = indices[i * 3 + 2]; + + float3 p1 = vertices[i1]; + float3 p2 = vertices[i2]; + float3 p3 = vertices[i3]; + + CTri t = new CTri(p1, p2, p3, i1, i2, i3); + + featureMatch(t, tris, input_mesh); + + if (t.mConcavity > 0.05f) + { + float v = t.getVolume(); + totalVolume += v; + ftris.Add(t); + } + } + + SplitPlane.computeSplitPlane(vertices, indices, ref plane); + cret = totalVolume; + } + + return cret; + } + + public static bool featureMatch(CTri m, List tris, List input_mesh) + { + bool ret = false; + float neardot = 0.707f; + m.mConcavity = 0; + + for (int i = 0; i < tris.Count; i++) + { + CTri t = tris[i]; + + if (t.samePlane(m)) + { + ret = false; + break; + } + + float dot = float3.dot(t.mNormal, m.mNormal); + + if (dot > neardot) + { + float d1 = t.planeDistance(m.mP1); + float d2 = t.planeDistance(m.mP2); + float d3 = t.planeDistance(m.mP3); + + if (d1 > 0.001f || d2 > 0.001f || d3 > 0.001f) // can't be near coplaner! + { + neardot = dot; + + t.raySect(m.mP1, m.mNormal, ref m.mNear1); + t.raySect(m.mP2, m.mNormal, ref m.mNear2); + t.raySect(m.mP3, m.mNormal, ref m.mNear3); + + ret = true; + } + } + } + + if (ret) + { + m.mC1 = m.mP1.Distance(m.mNear1); + m.mC2 = m.mP2.Distance(m.mNear2); + m.mC3 = m.mP3.Distance(m.mNear3); + + m.mConcavity = m.mC1; + + if (m.mC2 > m.mConcavity) + m.mConcavity = m.mC2; + if (m.mC3 > m.mConcavity) + m.mConcavity = m.mC3; + } + + return ret; + } + + private static float det(float3 p1, float3 p2, float3 p3) + { + return p1.x * p2.y * p3.z + p2.x * p3.y * p1.z + p3.x * p1.y * p2.z - p1.x * p3.y * p2.z - p2.x * p1.y * p3.z - p3.x * p2.y * p1.z; + } + + public static float computeMeshVolume(List vertices, List indices) + { + float volume = 0f; + + for (int i = 0; i < indices.Count / 3; i++) + { + float3 p1 = vertices[indices[i * 3 + 0]]; + float3 p2 = vertices[indices[i * 3 + 1]]; + float3 p3 = vertices[indices[i * 3 + 2]]; + + volume += det(p1, p2, p3); // compute the volume of the tetrahedran relative to the origin. + } + + volume *= (1.0f / 6.0f); + if (volume < 0f) + return -volume; + return volume; + } + + public static float computeMeshVolume2(List vertices, List indices) + { + float volume = 0f; + + float3 p0 = vertices[0]; + for (int i = 0; i < indices.Count / 3; i++) + { + float3 p1 = vertices[indices[i * 3 + 0]]; + float3 p2 = vertices[indices[i * 3 + 1]]; + float3 p3 = vertices[indices[i * 3 + 2]]; + + volume += tetVolume(p0, p1, p2, p3); // compute the volume of the tetrahedron relative to the root vertice + } + + return volume * (1.0f / 6.0f); + } + + private static float tetVolume(float3 p0, float3 p1, float3 p2, float3 p3) + { + float3 a = p1 - p0; + float3 b = p2 - p0; + float3 c = p3 - p0; + + float3 cross = float3.cross(b, c); + float volume = float3.dot(a, cross); + + if (volume < 0f) + return -volume; + return volume; + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs new file mode 100644 index 0000000..dfaede1 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs @@ -0,0 +1,411 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class DecompDesc + { + public List mVertices; + public List mIndices; + + // options + public uint mDepth; // depth to split, a maximum of 10, generally not over 7. + public float mCpercent; // the concavity threshold percentage. 0=20 is reasonable. + public float mPpercent; // the percentage volume conservation threshold to collapse hulls. 0-30 is reasonable. + + // hull output limits. + public uint mMaxVertices; // maximum number of vertices in the output hull. Recommended 32 or less. + public float mSkinWidth; // a skin width to apply to the output hulls. + + public ConvexDecompositionCallback mCallback; // the interface to receive back the results. + + public DecompDesc() + { + mDepth = 5; + mCpercent = 5; + mPpercent = 5; + mMaxVertices = 32; + } + } + + public class CHull + { + public float[] mMin = new float[3]; + public float[] mMax = new float[3]; + public float mVolume; + public float mDiagonal; + public ConvexResult mResult; + + public CHull(ConvexResult result) + { + mResult = new ConvexResult(result); + mVolume = Concavity.computeMeshVolume(result.HullVertices, result.HullIndices); + + mDiagonal = getBoundingRegion(result.HullVertices, mMin, mMax); + + float dx = mMax[0] - mMin[0]; + float dy = mMax[1] - mMin[1]; + float dz = mMax[2] - mMin[2]; + + dx *= 0.1f; // inflate 1/10th on each edge + dy *= 0.1f; // inflate 1/10th on each edge + dz *= 0.1f; // inflate 1/10th on each edge + + mMin[0] -= dx; + mMin[1] -= dy; + mMin[2] -= dz; + + mMax[0] += dx; + mMax[1] += dy; + mMax[2] += dz; + } + + public void Dispose() + { + mResult = null; + } + + public bool overlap(CHull h) + { + return overlapAABB(mMin, mMax, h.mMin, h.mMax); + } + + // returns the d1Giagonal distance + private static float getBoundingRegion(List points, float[] bmin, float[] bmax) + { + float3 first = points[0]; + + bmin[0] = first.x; + bmin[1] = first.y; + bmin[2] = first.z; + + bmax[0] = first.x; + bmax[1] = first.y; + bmax[2] = first.z; + + for (int i = 1; i < points.Count; i++) + { + float3 p = points[i]; + + if (p[0] < bmin[0]) bmin[0] = p[0]; + if (p[1] < bmin[1]) bmin[1] = p[1]; + if (p[2] < bmin[2]) bmin[2] = p[2]; + + if (p[0] > bmax[0]) bmax[0] = p[0]; + if (p[1] > bmax[1]) bmax[1] = p[1]; + if (p[2] > bmax[2]) bmax[2] = p[2]; + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + return (float)Math.Sqrt(dx * dx + dy * dy + dz * dz); + } + + // return true if the two AABB's overlap. + private static bool overlapAABB(float[] bmin1, float[] bmax1, float[] bmin2, float[] bmax2) + { + if (bmax2[0] < bmin1[0]) return false; // if the maximum is less than our minimum on any axis + if (bmax2[1] < bmin1[1]) return false; + if (bmax2[2] < bmin1[2]) return false; + + if (bmin2[0] > bmax1[0]) return false; // if the minimum is greater than our maximum on any axis + if (bmin2[1] > bmax1[1]) return false; // if the minimum is greater than our maximum on any axis + if (bmin2[2] > bmax1[2]) return false; // if the minimum is greater than our maximum on any axis + + return true; // the extents overlap + } + } + + public class ConvexBuilder + { + public List mChulls = new List(); + private ConvexDecompositionCallback mCallback; + + private int MAXDEPTH = 8; + private float CONCAVE_PERCENT = 1f; + private float MERGE_PERCENT = 2f; + + public ConvexBuilder(ConvexDecompositionCallback callback) + { + mCallback = callback; + } + + public void Dispose() + { + int i; + for (i = 0; i < mChulls.Count; i++) + { + CHull cr = mChulls[i]; + cr.Dispose(); + } + } + + public bool isDuplicate(uint i1, uint i2, uint i3, uint ci1, uint ci2, uint ci3) + { + uint dcount = 0; + + Debug.Assert(i1 != i2 && i1 != i3 && i2 != i3); + Debug.Assert(ci1 != ci2 && ci1 != ci3 && ci2 != ci3); + + if (i1 == ci1 || i1 == ci2 || i1 == ci3) + dcount++; + if (i2 == ci1 || i2 == ci2 || i2 == ci3) + dcount++; + if (i3 == ci1 || i3 == ci2 || i3 == ci3) + dcount++; + + return dcount == 3; + } + + public void getMesh(ConvexResult cr, VertexPool vc, List indices) + { + List src = cr.HullIndices; + + for (int i = 0; i < src.Count / 3; i++) + { + int i1 = src[i * 3 + 0]; + int i2 = src[i * 3 + 1]; + int i3 = src[i * 3 + 2]; + + float3 p1 = cr.HullVertices[i1]; + float3 p2 = cr.HullVertices[i2]; + float3 p3 = cr.HullVertices[i3]; + + i1 = vc.getIndex(p1); + i2 = vc.getIndex(p2); + i3 = vc.getIndex(p3); + } + } + + public CHull canMerge(CHull a, CHull b) + { + if (!a.overlap(b)) // if their AABB's (with a little slop) don't overlap, then return. + return null; + + CHull ret = null; + + // ok..we are going to combine both meshes into a single mesh + // and then we are going to compute the concavity... + + VertexPool vc = new VertexPool(); + + List indices = new List(); + + getMesh(a.mResult, vc, indices); + getMesh(b.mResult, vc, indices); + + int vcount = vc.GetSize(); + List vertices = vc.GetVertices(); + int tcount = indices.Count / 3; + + //don't do anything if hull is empty + if (tcount == 0) + { + vc.Clear(); + return null; + } + + HullResult hresult = new HullResult(); + HullDesc desc = new HullDesc(); + + desc.SetHullFlag(HullFlag.QF_TRIANGLES); + desc.Vertices = vertices; + + HullError hret = HullUtils.CreateConvexHull(desc, ref hresult); + + if (hret == HullError.QE_OK) + { + float combineVolume = Concavity.computeMeshVolume(hresult.OutputVertices, hresult.Indices); + float sumVolume = a.mVolume + b.mVolume; + + float percent = (sumVolume * 100) / combineVolume; + if (percent >= (100.0f - MERGE_PERCENT)) + { + ConvexResult cr = new ConvexResult(hresult.OutputVertices, hresult.Indices); + ret = new CHull(cr); + } + } + + vc.Clear(); + return ret; + } + + public bool combineHulls() + { + bool combine = false; + + sortChulls(mChulls); // sort the convex hulls, largest volume to least... + + List output = new List(); // the output hulls... + + int i; + for (i = 0; i < mChulls.Count && !combine; ++i) + { + CHull cr = mChulls[i]; + + int j; + for (j = 0; j < mChulls.Count; j++) + { + CHull match = mChulls[j]; + + if (cr != match) // don't try to merge a hull with itself, that be stoopid + { + + CHull merge = canMerge(cr, match); // if we can merge these two.... + + if (merge != null) + { + output.Add(merge); + + ++i; + while (i != mChulls.Count) + { + CHull cr2 = mChulls[i]; + if (cr2 != match) + { + output.Add(cr2); + } + i++; + } + + cr.Dispose(); + match.Dispose(); + combine = true; + break; + } + } + } + + if (combine) + { + break; + } + else + { + output.Add(cr); + } + } + + if (combine) + { + mChulls.Clear(); + mChulls = output; + output.Clear(); + } + + return combine; + } + + public int process(DecompDesc desc) + { + int ret = 0; + + MAXDEPTH = (int)desc.mDepth; + CONCAVE_PERCENT = desc.mCpercent; + MERGE_PERCENT = desc.mPpercent; + + ConvexDecomposition.calcConvexDecomposition(desc.mVertices, desc.mIndices, ConvexDecompResult, 0f, 0, MAXDEPTH, CONCAVE_PERCENT, MERGE_PERCENT); + + while (combineHulls()) // keep combinging hulls until I can't combine any more... + ; + + int i; + for (i = 0; i < mChulls.Count; i++) + { + CHull cr = mChulls[i]; + + // before we hand it back to the application, we need to regenerate the hull based on the + // limits given by the user. + + ConvexResult c = cr.mResult; // the high resolution hull... + + HullResult result = new HullResult(); + HullDesc hdesc = new HullDesc(); + + hdesc.SetHullFlag(HullFlag.QF_TRIANGLES); + + hdesc.Vertices = c.HullVertices; + hdesc.MaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output + + if (desc.mSkinWidth != 0f) + { + hdesc.SkinWidth = desc.mSkinWidth; + hdesc.SetHullFlag(HullFlag.QF_SKIN_WIDTH); // do skin width computation. + } + + HullError ret2 = HullUtils.CreateConvexHull(hdesc, ref result); + + if (ret2 == HullError.QE_OK) + { + ConvexResult r = new ConvexResult(result.OutputVertices, result.Indices); + + r.mHullVolume = Concavity.computeMeshVolume(result.OutputVertices, result.Indices); // the volume of the hull. + + // compute the best fit OBB + //computeBestFitOBB(result.mNumOutputVertices, result.mOutputVertices, sizeof(float) * 3, r.mOBBSides, r.mOBBTransform); + + //r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] * r.mOBBSides[2]; // compute the OBB volume. + + //fm_getTranslation(r.mOBBTransform, r.mOBBCenter); // get the translation component of the 4x4 matrix. + + //fm_matrixToQuat(r.mOBBTransform, r.mOBBOrientation); // extract the orientation as a quaternion. + + //r.mSphereRadius = computeBoundingSphere(result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter); + //r.mSphereVolume = fm_sphereVolume(r.mSphereRadius); + + mCallback(r); + } + + result = null; + cr.Dispose(); + } + + ret = mChulls.Count; + + mChulls.Clear(); + + return ret; + } + + public void ConvexDecompResult(ConvexResult result) + { + CHull ch = new CHull(result); + mChulls.Add(ch); + } + + public void sortChulls(List hulls) + { + hulls.Sort(delegate(CHull a, CHull b) { return a.mVolume.CompareTo(b.mVolume); }); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs new file mode 100644 index 0000000..2e2bb70 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs @@ -0,0 +1,200 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public delegate void ConvexDecompositionCallback(ConvexResult result); + + public class FaceTri + { + public float3 P1; + public float3 P2; + public float3 P3; + + public FaceTri() { } + + public FaceTri(List vertices, int i1, int i2, int i3) + { + P1 = new float3(vertices[i1]); + P2 = new float3(vertices[i2]); + P3 = new float3(vertices[i3]); + } + } + + public static class ConvexDecomposition + { + private static void addTri(VertexPool vl, List list, float3 p1, float3 p2, float3 p3) + { + int i1 = vl.getIndex(p1); + int i2 = vl.getIndex(p2); + int i3 = vl.getIndex(p3); + + // do *not* process degenerate triangles! + if ( i1 != i2 && i1 != i3 && i2 != i3 ) + { + list.Add(i1); + list.Add(i2); + list.Add(i3); + } + } + + public static void calcConvexDecomposition(List vertices, List indices, ConvexDecompositionCallback callback, float masterVolume, int depth, + int maxDepth, float concavePercent, float mergePercent) + { + float4 plane = new float4(); + bool split = false; + + if (depth < maxDepth) + { + float volume = 0f; + float c = Concavity.computeConcavity(vertices, indices, ref plane, ref volume); + + if (depth == 0) + { + masterVolume = volume; + } + + float percent = (c * 100.0f) / masterVolume; + + if (percent > concavePercent) // if great than 5% of the total volume is concave, go ahead and keep splitting. + { + split = true; + } + } + + if (depth >= maxDepth || !split) + { + HullResult result = new HullResult(); + HullDesc desc = new HullDesc(); + + desc.SetHullFlag(HullFlag.QF_TRIANGLES); + + desc.Vertices = vertices; + + HullError ret = HullUtils.CreateConvexHull(desc, ref result); + + if (ret == HullError.QE_OK) + { + ConvexResult r = new ConvexResult(result.OutputVertices, result.Indices); + callback(r); + } + + return; + } + + List ifront = new List(); + List iback = new List(); + + VertexPool vfront = new VertexPool(); + VertexPool vback = new VertexPool(); + + // ok..now we are going to 'split' all of the input triangles against this plane! + for (int i = 0; i < indices.Count / 3; i++) + { + int i1 = indices[i * 3 + 0]; + int i2 = indices[i * 3 + 1]; + int i3 = indices[i * 3 + 2]; + + FaceTri t = new FaceTri(vertices, i1, i2, i3); + + float3[] front = new float3[4]; + float3[] back = new float3[4]; + + int fcount = 0; + int bcount = 0; + + PlaneTriResult result = PlaneTri.planeTriIntersection(plane, t, 0.00001f, ref front, out fcount, ref back, out bcount); + + if (fcount > 4 || bcount > 4) + { + result = PlaneTri.planeTriIntersection(plane, t, 0.00001f, ref front, out fcount, ref back, out bcount); + } + + switch (result) + { + case PlaneTriResult.PTR_FRONT: + Debug.Assert(fcount == 3); + addTri(vfront, ifront, front[0], front[1], front[2]); + break; + case PlaneTriResult.PTR_BACK: + Debug.Assert(bcount == 3); + addTri(vback, iback, back[0], back[1], back[2]); + break; + case PlaneTriResult.PTR_SPLIT: + Debug.Assert(fcount >= 3 && fcount <= 4); + Debug.Assert(bcount >= 3 && bcount <= 4); + + addTri(vfront, ifront, front[0], front[1], front[2]); + addTri(vback, iback, back[0], back[1], back[2]); + + if (fcount == 4) + { + addTri(vfront, ifront, front[0], front[2], front[3]); + } + + if (bcount == 4) + { + addTri(vback, iback, back[0], back[2], back[3]); + } + + break; + } + } + + // ok... here we recursively call + if (ifront.Count > 0) + { + int vcount = vfront.GetSize(); + List vertices2 = vfront.GetVertices(); + for (int i = 0; i < vertices2.Count; i++) + vertices2[i] = new float3(vertices2[i]); + int tcount = ifront.Count / 3; + + calcConvexDecomposition(vertices2, ifront, callback, masterVolume, depth + 1, maxDepth, concavePercent, mergePercent); + } + + ifront.Clear(); + vfront.Clear(); + + if (iback.Count > 0) + { + int vcount = vback.GetSize(); + List vertices2 = vback.GetVertices(); + int tcount = iback.Count / 3; + + calcConvexDecomposition(vertices2, iback, callback, masterVolume, depth + 1, maxDepth, concavePercent, mergePercent); + } + + iback.Clear(); + vback.Clear(); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs new file mode 100644 index 0000000..87758b5 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs @@ -0,0 +1,74 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class ConvexResult + { + public List HullVertices; + public List HullIndices; + + public float mHullVolume; // the volume of the convex hull. + + //public float[] OBBSides = new float[3]; // the width, height and breadth of the best fit OBB + //public float[] OBBCenter = new float[3]; // the center of the OBB + //public float[] OBBOrientation = new float[4]; // the quaternion rotation of the OBB. + //public float[] OBBTransform = new float[16]; // the 4x4 transform of the OBB. + //public float OBBVolume; // the volume of the OBB + + //public float SphereRadius; // radius and center of best fit sphere + //public float[] SphereCenter = new float[3]; + //public float SphereVolume; // volume of the best fit sphere + + public ConvexResult() + { + HullVertices = new List(); + HullIndices = new List(); + } + + public ConvexResult(List hvertices, List hindices) + { + HullVertices = hvertices; + HullIndices = hindices; + } + + public ConvexResult(ConvexResult r) + { + HullVertices = new List(r.HullVertices); + HullIndices = new List(r.HullIndices); + } + + public void Dispose() + { + HullVertices = null; + HullIndices = null; + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs new file mode 100644 index 0000000..d81df26 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs @@ -0,0 +1,171 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class HullResult + { + public bool Polygons = true; // true if indices represents polygons, false indices are triangles + public List OutputVertices = new List(); + public List Indices; + + // If triangles, then indices are array indexes into the vertex list. + // If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. + } + + public class PHullResult + { + public List Vertices = new List(); + public List Indices = new List(); + } + + [Flags] + public enum HullFlag : int + { + QF_DEFAULT = 0, + QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons. + QF_SKIN_WIDTH = (1 << 2) // extrude hull based on this skin width + } + + public enum HullError : int + { + QE_OK, // success! + QE_FAIL // failed. + } + + public class HullDesc + { + public HullFlag Flags; // flags to use when generating the convex hull. + public List Vertices; + public float NormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. + public float SkinWidth; + public uint MaxVertices; // maximum number of vertices to be considered for the hull! + public uint MaxFaces; + + public HullDesc() + { + Flags = HullFlag.QF_DEFAULT; + Vertices = new List(); + NormalEpsilon = 0.001f; + MaxVertices = 4096; + MaxFaces = 4096; + SkinWidth = 0.01f; + } + + public HullDesc(HullFlag flags, List vertices) + { + Flags = flags; + Vertices = new List(vertices); + NormalEpsilon = 0.001f; + MaxVertices = 4096; + MaxFaces = 4096; + SkinWidth = 0.01f; + } + + public bool HasHullFlag(HullFlag flag) + { + return (Flags & flag) != 0; + } + + public void SetHullFlag(HullFlag flag) + { + Flags |= flag; + } + + public void ClearHullFlag(HullFlag flag) + { + Flags &= ~flag; + } + } + + public class ConvexH + { + public struct HalfEdge + { + public short ea; // the other half of the edge (index into edges list) + public byte v; // the vertex at the start of this edge (index into vertices list) + public byte p; // the facet on which this edge lies (index into facets list) + + public HalfEdge(short _ea, byte _v, byte _p) + { + ea = _ea; + v = _v; + p = _p; + } + + public HalfEdge(HalfEdge e) + { + ea = e.ea; + v = e.v; + p = e.p; + } + } + + public List vertices = new List(); + public List edges = new List(); + public List facets = new List(); + + public ConvexH(int vertices_size, int edges_size, int facets_size) + { + vertices = new List(vertices_size); + edges = new List(edges_size); + facets = new List(facets_size); + } + } + + public class VertFlag + { + public byte planetest; + public byte junk; + public byte undermap; + public byte overmap; + } + + public class EdgeFlag + { + public byte planetest; + public byte fixes; + public short undermap; + public short overmap; + } + + public class PlaneFlag + { + public byte undermap; + public byte overmap; + } + + public class Coplanar + { + public ushort ea; + public byte v0; + public byte v1; + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs new file mode 100644 index 0000000..1119a75 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs @@ -0,0 +1,99 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class HullTriangle : int3 + { + public int3 n = new int3(); + public int id; + public int vmax; + public float rise; + private List tris; + + public HullTriangle(int a, int b, int c, List tris) + : base(a, b, c) + { + this.tris = tris; + + n = new int3(-1, -1, -1); + id = tris.Count; + tris.Add(this); + vmax = -1; + rise = 0.0f; + } + + public void Dispose() + { + Debug.Assert(tris[id] == this); + tris[id] = null; + } + + public int neib(int a, int b) + { + int i; + + for (i = 0; i < 3; i++) + { + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + if ((this)[i] == a && (this)[i1] == b) + return n[i2]; + if ((this)[i] == b && (this)[i1] == a) + return n[i2]; + } + + Debug.Assert(false); + return -1; + } + + public void setneib(int a, int b, int value) + { + int i; + + for (i = 0; i < 3; i++) + { + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + if ((this)[i] == a && (this)[i1] == b) + { + n[i2] = value; + return; + } + if ((this)[i] == b && (this)[i1] == a) + { + n[i2] = value; + return; + } + } + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs new file mode 100644 index 0000000..c9ccfe2 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs @@ -0,0 +1,1868 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public static class HullUtils + { + public static int argmin(float[] a, int n) + { + int r = 0; + for (int i = 1; i < n; i++) + { + if (a[i] < a[r]) + { + r = i; + } + } + return r; + } + + public static float clampf(float a) + { + return Math.Min(1.0f, Math.Max(0.0f, a)); + } + + public static float Round(float a, float precision) + { + return (float)Math.Floor(0.5f + a / precision) * precision; + } + + public static float Interpolate(float f0, float f1, float alpha) + { + return f0 * (1 - alpha) + f1 * alpha; + } + + public static void Swap(ref T a, ref T b) + { + T tmp = a; + a = b; + b = tmp; + } + + public static bool above(List vertices, int3 t, float3 p, float epsilon) + { + float3 vtx = vertices[t.x]; + float3 n = TriNormal(vtx, vertices[t.y], vertices[t.z]); + return (float3.dot(n, p - vtx) > epsilon); // EPSILON??? + } + + public static int hasedge(int3 t, int a, int b) + { + for (int i = 0; i < 3; i++) + { + int i1 = (i + 1) % 3; + if (t[i] == a && t[i1] == b) + return 1; + } + return 0; + } + + public static bool hasvert(int3 t, int v) + { + return (t[0] == v || t[1] == v || t[2] == v); + } + + public static int shareedge(int3 a, int3 b) + { + int i; + for (i = 0; i < 3; i++) + { + int i1 = (i + 1) % 3; + if (hasedge(a, b[i1], b[i]) != 0) + return 1; + } + return 0; + } + + public static void b2bfix(HullTriangle s, HullTriangle t, List tris) + { + int i; + for (i = 0; i < 3; i++) + { + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + int a = (s)[i1]; + int b = (s)[i2]; + Debug.Assert(tris[s.neib(a, b)].neib(b, a) == s.id); + Debug.Assert(tris[t.neib(a, b)].neib(b, a) == t.id); + tris[s.neib(a, b)].setneib(b, a, t.neib(b, a)); + tris[t.neib(b, a)].setneib(a, b, s.neib(a, b)); + } + } + + public static void removeb2b(HullTriangle s, HullTriangle t, List tris) + { + b2bfix(s, t, tris); + s.Dispose(); + t.Dispose(); + } + + public static void checkit(HullTriangle t, List tris) + { + int i; + Debug.Assert(tris[t.id] == t); + for (i = 0; i < 3; i++) + { + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + int a = (t)[i1]; + int b = (t)[i2]; + Debug.Assert(a != b); + Debug.Assert(tris[t.n[i]].neib(b, a) == t.id); + } + } + + public static void extrude(HullTriangle t0, int v, List tris) + { + int3 t = t0; + int n = tris.Count; + HullTriangle ta = new HullTriangle(v, t[1], t[2], tris); + ta.n = new int3(t0.n[0], n + 1, n + 2); + tris[t0.n[0]].setneib(t[1], t[2], n + 0); + HullTriangle tb = new HullTriangle(v, t[2], t[0], tris); + tb.n = new int3(t0.n[1], n + 2, n + 0); + tris[t0.n[1]].setneib(t[2], t[0], n + 1); + HullTriangle tc = new HullTriangle(v, t[0], t[1], tris); + tc.n = new int3(t0.n[2], n + 0, n + 1); + tris[t0.n[2]].setneib(t[0], t[1], n + 2); + checkit(ta, tris); + checkit(tb, tris); + checkit(tc, tris); + if (hasvert(tris[ta.n[0]], v)) + removeb2b(ta, tris[ta.n[0]], tris); + if (hasvert(tris[tb.n[0]], v)) + removeb2b(tb, tris[tb.n[0]], tris); + if (hasvert(tris[tc.n[0]], v)) + removeb2b(tc, tris[tc.n[0]], tris); + t0.Dispose(); + } + + public static HullTriangle extrudable(float epsilon, List tris) + { + int i; + HullTriangle t = null; + for (i = 0; i < tris.Count; i++) + { + if (t == null || (tris.Count > i && (object)tris[i] != null && t.rise < tris[i].rise)) + { + t = tris[i]; + } + } + return (t.rise > epsilon) ? t : null; + } + + public static Quaternion RotationArc(float3 v0, float3 v1) + { + Quaternion q = new Quaternion(); + v0 = float3.normalize(v0); // Comment these two lines out if you know its not needed. + v1 = float3.normalize(v1); // If vector is already unit length then why do it again? + float3 c = float3.cross(v0, v1); + float d = float3.dot(v0, v1); + if (d <= -1.0f) // 180 about x axis + { + return new Quaternion(1f, 0f, 0f, 0f); + } + float s = (float)Math.Sqrt((1 + d) * 2f); + q.x = c.x / s; + q.y = c.y / s; + q.z = c.z / s; + q.w = s / 2.0f; + return q; + } + + public static float3 PlaneLineIntersection(Plane plane, float3 p0, float3 p1) + { + // returns the point where the line p0-p1 intersects the plane n&d + float3 dif = p1 - p0; + float dn = float3.dot(plane.normal, dif); + float t = -(plane.dist + float3.dot(plane.normal, p0)) / dn; + return p0 + (dif * t); + } + + public static float3 LineProject(float3 p0, float3 p1, float3 a) + { + float3 w = new float3(); + w = p1 - p0; + float t = float3.dot(w, (a - p0)) / (w.x * w.x + w.y * w.y + w.z * w.z); + return p0 + w * t; + } + + public static float3 PlaneProject(Plane plane, float3 point) + { + return point - plane.normal * (float3.dot(point, plane.normal) + plane.dist); + } + + public static float LineProjectTime(float3 p0, float3 p1, float3 a) + { + float3 w = new float3(); + w = p1 - p0; + float t = float3.dot(w, (a - p0)) / (w.x * w.x + w.y * w.y + w.z * w.z); + return t; + } + + public static float3 ThreePlaneIntersection(Plane p0, Plane p1, Plane p2) + { + float3x3 mp = float3x3.Transpose(new float3x3(p0.normal, p1.normal, p2.normal)); + float3x3 mi = float3x3.Inverse(mp); + float3 b = new float3(p0.dist, p1.dist, p2.dist); + return -b * mi; + } + + public static bool PolyHit(List vert, float3 v0, float3 v1) + { + float3 impact = new float3(); + float3 normal = new float3(); + return PolyHit(vert, v0, v1, out impact, out normal); + } + + public static bool PolyHit(List vert, float3 v0, float3 v1, out float3 impact) + { + float3 normal = new float3(); + return PolyHit(vert, v0, v1, out impact, out normal); + } + + public static bool PolyHit(List vert, float3 v0, float3 v1, out float3 impact, out float3 normal) + { + float3 the_point = new float3(); + + impact = null; + normal = null; + + int i; + float3 nrml = new float3(0, 0, 0); + for (i = 0; i < vert.Count; i++) + { + int i1 = (i + 1) % vert.Count; + int i2 = (i + 2) % vert.Count; + nrml = nrml + float3.cross(vert[i1] - vert[i], vert[i2] - vert[i1]); + } + + float m = float3.magnitude(nrml); + if (m == 0.0) + { + return false; + } + nrml = nrml * (1.0f / m); + float dist = -float3.dot(nrml, vert[0]); + float d0; + float d1; + if ((d0 = float3.dot(v0, nrml) + dist) < 0 || (d1 = float3.dot(v1, nrml) + dist) > 0) + { + return false; + } + + // By using the cached plane distances d0 and d1 + // we can optimize the following: + // the_point = planelineintersection(nrml,dist,v0,v1); + float a = d0 / (d0 - d1); + the_point = v0 * (1 - a) + v1 * a; + + + bool inside = true; + for (int j = 0; inside && j < vert.Count; j++) + { + // let inside = 0 if outside + float3 pp1 = new float3(); + float3 pp2 = new float3(); + float3 side = new float3(); + pp1 = vert[j]; + pp2 = vert[(j + 1) % vert.Count]; + side = float3.cross((pp2 - pp1), (the_point - pp1)); + inside = (float3.dot(nrml, side) >= 0.0); + } + if (inside) + { + if (normal != null) + { + normal = nrml; + } + if (impact != null) + { + impact = the_point; + } + } + return inside; + } + + public static bool BoxInside(float3 p, float3 bmin, float3 bmax) + { + return (p.x >= bmin.x && p.x <= bmax.x && p.y >= bmin.y && p.y <= bmax.y && p.z >= bmin.z && p.z <= bmax.z); + } + + public static bool BoxIntersect(float3 v0, float3 v1, float3 bmin, float3 bmax, float3 impact) + { + if (BoxInside(v0, bmin, bmax)) + { + impact = v0; + return true; + } + if (v0.x <= bmin.x && v1.x >= bmin.x) + { + float a = (bmin.x - v0.x) / (v1.x - v0.x); + //v.x = bmin.x; + float vy = (1 - a) * v0.y + a * v1.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z) + { + impact.x = bmin.x; + impact.y = vy; + impact.z = vz; + return true; + } + } + else if (v0.x >= bmax.x && v1.x <= bmax.x) + { + float a = (bmax.x - v0.x) / (v1.x - v0.x); + //v.x = bmax.x; + float vy = (1 - a) * v0.y + a * v1.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z) + { + impact.x = bmax.x; + impact.y = vy; + impact.z = vz; + return true; + } + } + if (v0.y <= bmin.y && v1.y >= bmin.y) + { + float a = (bmin.y - v0.y) / (v1.y - v0.y); + float vx = (1 - a) * v0.x + a * v1.x; + //v.y = bmin.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z) + { + impact.x = vx; + impact.y = bmin.y; + impact.z = vz; + return true; + } + } + else if (v0.y >= bmax.y && v1.y <= bmax.y) + { + float a = (bmax.y - v0.y) / (v1.y - v0.y); + float vx = (1 - a) * v0.x + a * v1.x; + // vy = bmax.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z) + { + impact.x = vx; + impact.y = bmax.y; + impact.z = vz; + return true; + } + } + if (v0.z <= bmin.z && v1.z >= bmin.z) + { + float a = (bmin.z - v0.z) / (v1.z - v0.z); + float vx = (1 - a) * v0.x + a * v1.x; + float vy = (1 - a) * v0.y + a * v1.y; + // v.z = bmin.z; + if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x) + { + impact.x = vx; + impact.y = vy; + impact.z = bmin.z; + return true; + } + } + else if (v0.z >= bmax.z && v1.z <= bmax.z) + { + float a = (bmax.z - v0.z) / (v1.z - v0.z); + float vx = (1 - a) * v0.x + a * v1.x; + float vy = (1 - a) * v0.y + a * v1.y; + // v.z = bmax.z; + if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x) + { + impact.x = vx; + impact.y = vy; + impact.z = bmax.z; + return true; + } + } + return false; + } + + public static float DistanceBetweenLines(float3 ustart, float3 udir, float3 vstart, float3 vdir, float3 upoint) + { + return DistanceBetweenLines(ustart, udir, vstart, vdir, upoint, null); + } + + public static float DistanceBetweenLines(float3 ustart, float3 udir, float3 vstart, float3 vdir) + { + return DistanceBetweenLines(ustart, udir, vstart, vdir, null, null); + } + + public static float DistanceBetweenLines(float3 ustart, float3 udir, float3 vstart, float3 vdir, float3 upoint, float3 vpoint) + { + float3 cp = float3.normalize(float3.cross(udir, vdir)); + + float distu = -float3.dot(cp, ustart); + float distv = -float3.dot(cp, vstart); + float dist = (float)Math.Abs(distu - distv); + if (upoint != null) + { + Plane plane = new Plane(); + plane.normal = float3.normalize(float3.cross(vdir, cp)); + plane.dist = -float3.dot(plane.normal, vstart); + upoint = PlaneLineIntersection(plane, ustart, ustart + udir); + } + if (vpoint != null) + { + Plane plane = new Plane(); + plane.normal = float3.normalize(float3.cross(udir, cp)); + plane.dist = -float3.dot(plane.normal, ustart); + vpoint = PlaneLineIntersection(plane, vstart, vstart + vdir); + } + return dist; + } + + public static float3 TriNormal(float3 v0, float3 v1, float3 v2) + { + // return the normal of the triangle + // inscribed by v0, v1, and v2 + float3 cp = float3.cross(v1 - v0, v2 - v1); + float m = float3.magnitude(cp); + if (m == 0) + return new float3(1, 0, 0); + return cp * (1.0f / m); + } + + public static int PlaneTest(Plane p, float3 v, float planetestepsilon) + { + float a = float3.dot(v, p.normal) + p.dist; + int flag = (a > planetestepsilon) ? (2) : ((a < -planetestepsilon) ? (1) : (0)); + return flag; + } + + public static int SplitTest(ref ConvexH convex, Plane plane, float planetestepsilon) + { + int flag = 0; + for (int i = 0; i < convex.vertices.Count; i++) + { + flag |= PlaneTest(plane, convex.vertices[i], planetestepsilon); + } + return flag; + } + + public static Quaternion VirtualTrackBall(float3 cop, float3 cor, float3 dir1, float3 dir2) + { + // routine taken from game programming gems. + // Implement track ball functionality to spin stuf on the screen + // cop center of projection + // cor center of rotation + // dir1 old mouse direction + // dir2 new mouse direction + // pretend there is a sphere around cor. Then find the points + // where dir1 and dir2 intersect that sphere. Find the + // rotation that takes the first point to the second. + float m; + // compute plane + float3 nrml = cor - cop; + float fudgefactor = 1.0f / (float3.magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop + nrml = float3.normalize(nrml); + float dist = -float3.dot(nrml, cor); + float3 u = PlaneLineIntersection(new Plane(nrml, dist), cop, cop + dir1); + u = u - cor; + u = u * fudgefactor; + m = float3.magnitude(u); + if (m > 1) + { + u /= m; + } + else + { + u = u - (nrml * (float)Math.Sqrt(1 - m * m)); + } + float3 v = PlaneLineIntersection(new Plane(nrml, dist), cop, cop + dir2); + v = v - cor; + v = v * fudgefactor; + m = float3.magnitude(v); + if (m > 1) + { + v /= m; + } + else + { + v = v - (nrml * (float)Math.Sqrt(1 - m * m)); + } + return RotationArc(u, v); + } + + public static bool AssertIntact(ConvexH convex, float planetestepsilon) + { + int i; + int estart = 0; + for (i = 0; i < convex.edges.Count; i++) + { + if (convex.edges[estart].p != convex.edges[i].p) + { + estart = i; + } + int inext = i + 1; + if (inext >= convex.edges.Count || convex.edges[inext].p != convex.edges[i].p) + { + inext = estart; + } + Debug.Assert(convex.edges[inext].p == convex.edges[i].p); + int nb = convex.edges[i].ea; + Debug.Assert(nb != 255); + if (nb == 255 || nb == -1) + return false; + Debug.Assert(nb != -1); + Debug.Assert(i == convex.edges[nb].ea); + } + for (i = 0; i < convex.edges.Count; i++) + { + Debug.Assert((0) == PlaneTest(convex.facets[convex.edges[i].p], convex.vertices[convex.edges[i].v], planetestepsilon)); + if ((0) != PlaneTest(convex.facets[convex.edges[i].p], convex.vertices[convex.edges[i].v], planetestepsilon)) + return false; + if (convex.edges[estart].p != convex.edges[i].p) + { + estart = i; + } + int i1 = i + 1; + if (i1 >= convex.edges.Count || convex.edges[i1].p != convex.edges[i].p) + { + i1 = estart; + } + int i2 = i1 + 1; + if (i2 >= convex.edges.Count || convex.edges[i2].p != convex.edges[i].p) + { + i2 = estart; + } + if (i == i2) // i sliced tangent to an edge and created 2 meaningless edges + continue; + float3 localnormal = TriNormal(convex.vertices[convex.edges[i].v], convex.vertices[convex.edges[i1].v], convex.vertices[convex.edges[i2].v]); + Debug.Assert(float3.dot(localnormal, convex.facets[convex.edges[i].p].normal) > 0); + if (float3.dot(localnormal, convex.facets[convex.edges[i].p].normal) <= 0) + return false; + } + return true; + } + + public static ConvexH test_btbq(float planetestepsilon) + { + // back to back quads + ConvexH convex = new ConvexH(4, 8, 2); + convex.vertices[0] = new float3(0, 0, 0); + convex.vertices[1] = new float3(1, 0, 0); + convex.vertices[2] = new float3(1, 1, 0); + convex.vertices[3] = new float3(0, 1, 0); + convex.facets[0] = new Plane(new float3(0, 0, 1), 0); + convex.facets[1] = new Plane(new float3(0, 0, -1), 0); + convex.edges[0] = new ConvexH.HalfEdge(7, 0, 0); + convex.edges[1] = new ConvexH.HalfEdge(6, 1, 0); + convex.edges[2] = new ConvexH.HalfEdge(5, 2, 0); + convex.edges[3] = new ConvexH.HalfEdge(4, 3, 0); + + convex.edges[4] = new ConvexH.HalfEdge(3, 0, 1); + convex.edges[5] = new ConvexH.HalfEdge(2, 3, 1); + convex.edges[6] = new ConvexH.HalfEdge(1, 2, 1); + convex.edges[7] = new ConvexH.HalfEdge(0, 1, 1); + AssertIntact(convex, planetestepsilon); + return convex; + } + + public static ConvexH test_cube() + { + ConvexH convex = new ConvexH(8, 24, 6); + convex.vertices[0] = new float3(0, 0, 0); + convex.vertices[1] = new float3(0, 0, 1); + convex.vertices[2] = new float3(0, 1, 0); + convex.vertices[3] = new float3(0, 1, 1); + convex.vertices[4] = new float3(1, 0, 0); + convex.vertices[5] = new float3(1, 0, 1); + convex.vertices[6] = new float3(1, 1, 0); + convex.vertices[7] = new float3(1, 1, 1); + + convex.facets[0] = new Plane(new float3(-1, 0, 0), 0); + convex.facets[1] = new Plane(new float3(1, 0, 0), -1); + convex.facets[2] = new Plane(new float3(0, -1, 0), 0); + convex.facets[3] = new Plane(new float3(0, 1, 0), -1); + convex.facets[4] = new Plane(new float3(0, 0, -1), 0); + convex.facets[5] = new Plane(new float3(0, 0, 1), -1); + + convex.edges[0] = new ConvexH.HalfEdge(11, 0, 0); + convex.edges[1] = new ConvexH.HalfEdge(23, 1, 0); + convex.edges[2] = new ConvexH.HalfEdge(15, 3, 0); + convex.edges[3] = new ConvexH.HalfEdge(16, 2, 0); + + convex.edges[4] = new ConvexH.HalfEdge(13, 6, 1); + convex.edges[5] = new ConvexH.HalfEdge(21, 7, 1); + convex.edges[6] = new ConvexH.HalfEdge(9, 5, 1); + convex.edges[7] = new ConvexH.HalfEdge(18, 4, 1); + + convex.edges[8] = new ConvexH.HalfEdge(19, 0, 2); + convex.edges[9] = new ConvexH.HalfEdge(6, 4, 2); + convex.edges[10] = new ConvexH.HalfEdge(20, 5, 2); + convex.edges[11] = new ConvexH.HalfEdge(0, 1, 2); + + convex.edges[12] = new ConvexH.HalfEdge(22, 3, 3); + convex.edges[13] = new ConvexH.HalfEdge(4, 7, 3); + convex.edges[14] = new ConvexH.HalfEdge(17, 6, 3); + convex.edges[15] = new ConvexH.HalfEdge(2, 2, 3); + + convex.edges[16] = new ConvexH.HalfEdge(3, 0, 4); + convex.edges[17] = new ConvexH.HalfEdge(14, 2, 4); + convex.edges[18] = new ConvexH.HalfEdge(7, 6, 4); + convex.edges[19] = new ConvexH.HalfEdge(8, 4, 4); + + convex.edges[20] = new ConvexH.HalfEdge(10, 1, 5); + convex.edges[21] = new ConvexH.HalfEdge(5, 5, 5); + convex.edges[22] = new ConvexH.HalfEdge(12, 7, 5); + convex.edges[23] = new ConvexH.HalfEdge(1, 3, 5); + + return convex; + } + + public static ConvexH ConvexHMakeCube(float3 bmin, float3 bmax) + { + ConvexH convex = test_cube(); + convex.vertices[0] = new float3(bmin.x, bmin.y, bmin.z); + convex.vertices[1] = new float3(bmin.x, bmin.y, bmax.z); + convex.vertices[2] = new float3(bmin.x, bmax.y, bmin.z); + convex.vertices[3] = new float3(bmin.x, bmax.y, bmax.z); + convex.vertices[4] = new float3(bmax.x, bmin.y, bmin.z); + convex.vertices[5] = new float3(bmax.x, bmin.y, bmax.z); + convex.vertices[6] = new float3(bmax.x, bmax.y, bmin.z); + convex.vertices[7] = new float3(bmax.x, bmax.y, bmax.z); + + convex.facets[0] = new Plane(new float3(-1, 0, 0), bmin.x); + convex.facets[1] = new Plane(new float3(1, 0, 0), -bmax.x); + convex.facets[2] = new Plane(new float3(0, -1, 0), bmin.y); + convex.facets[3] = new Plane(new float3(0, 1, 0), -bmax.y); + convex.facets[4] = new Plane(new float3(0, 0, -1), bmin.z); + convex.facets[5] = new Plane(new float3(0, 0, 1), -bmax.z); + return convex; + } + + public static ConvexH ConvexHCrop(ref ConvexH convex, Plane slice, float planetestepsilon) + { + int i; + int vertcountunder = 0; + int vertcountover = 0; + List vertscoplanar = new List(); // existing vertex members of convex that are coplanar + List edgesplit = new List(); // existing edges that members of convex that cross the splitplane + + Debug.Assert(convex.edges.Count < 480); + + EdgeFlag[] edgeflag = new EdgeFlag[512]; + VertFlag[] vertflag = new VertFlag[256]; + PlaneFlag[] planeflag = new PlaneFlag[128]; + ConvexH.HalfEdge[] tmpunderedges = new ConvexH.HalfEdge[512]; + Plane[] tmpunderplanes = new Plane[128]; + Coplanar[] coplanaredges = new Coplanar[512]; + int coplanaredges_num = 0; + + List createdverts = new List(); + + // do the side-of-plane tests + for (i = 0; i < convex.vertices.Count; i++) + { + vertflag[i].planetest = (byte)PlaneTest(slice, convex.vertices[i], planetestepsilon); + if (vertflag[i].planetest == (0)) + { + // ? vertscoplanar.Add(i); + vertflag[i].undermap = (byte)vertcountunder++; + vertflag[i].overmap = (byte)vertcountover++; + } + else if (vertflag[i].planetest == (1)) + { + vertflag[i].undermap = (byte)vertcountunder++; + } + else + { + Debug.Assert(vertflag[i].planetest == (2)); + vertflag[i].overmap = (byte)vertcountover++; + vertflag[i].undermap = 255; // for debugging purposes + } + } + int vertcountunderold = vertcountunder; // for debugging only + + int under_edge_count = 0; + int underplanescount = 0; + int e0 = 0; + + for (int currentplane = 0; currentplane < convex.facets.Count; currentplane++) + { + int estart = e0; + int enextface = 0; + int planeside = 0; + int e1 = e0 + 1; + int vout = -1; + int vin = -1; + int coplanaredge = -1; + do + { + + if (e1 >= convex.edges.Count || convex.edges[e1].p != currentplane) + { + enextface = e1; + e1 = estart; + } + ConvexH.HalfEdge edge0 = convex.edges[e0]; + ConvexH.HalfEdge edge1 = convex.edges[e1]; + ConvexH.HalfEdge edgea = convex.edges[edge0.ea]; + + planeside |= vertflag[edge0.v].planetest; + //if((vertflag[edge0.v].planetest & vertflag[edge1.v].planetest) == COPLANAR) { + // assert(ecop==-1); + // ecop=e; + //} + + if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (2)) + { + // both endpoints over plane + edgeflag[e0].undermap = -1; + } + else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == (1)) + { + // at least one endpoint under, the other coplanar or under + + edgeflag[e0].undermap = (short)under_edge_count; + tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; + tmpunderedges[under_edge_count].p = (byte)underplanescount; + if (edge0.ea < e0) + { + // connect the neighbors + Debug.Assert(edgeflag[edge0.ea].undermap != -1); + tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; + tmpunderedges[edgeflag[edge0.ea].undermap].ea = (short)under_edge_count; + } + under_edge_count++; + } + else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == (0)) + { + // both endpoints coplanar + // must check a 3rd point to see if UNDER + int e2 = e1 + 1; + if (e2 >= convex.edges.Count || convex.edges[e2].p != currentplane) + { + e2 = estart; + } + Debug.Assert(convex.edges[e2].p == currentplane); + ConvexH.HalfEdge edge2 = convex.edges[e2]; + if (vertflag[edge2.v].planetest == (1)) + { + + edgeflag[e0].undermap = (short)under_edge_count; + tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; + tmpunderedges[under_edge_count].p = (byte)underplanescount; + tmpunderedges[under_edge_count].ea = -1; + // make sure this edge is added to the "coplanar" list + coplanaredge = under_edge_count; + vout = vertflag[edge0.v].undermap; + vin = vertflag[edge1.v].undermap; + under_edge_count++; + } + else + { + edgeflag[e0].undermap = -1; + } + } + else if (vertflag[edge0.v].planetest == (1) && vertflag[edge1.v].planetest == (2)) + { + // first is under 2nd is over + + edgeflag[e0].undermap = (short)under_edge_count; + tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; + tmpunderedges[under_edge_count].p = (byte)underplanescount; + if (edge0.ea < e0) + { + Debug.Assert(edgeflag[edge0.ea].undermap != -1); + // connect the neighbors + tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; + tmpunderedges[edgeflag[edge0.ea].undermap].ea = (short)under_edge_count; + vout = tmpunderedges[edgeflag[edge0.ea].undermap].v; + } + else + { + Plane p0 = convex.facets[edge0.p]; + Plane pa = convex.facets[edgea.p]; + createdverts.Add(ThreePlaneIntersection(p0, pa, slice)); + //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]))); + //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])); + vout = vertcountunder++; + } + under_edge_count++; + /// hmmm something to think about: i might be able to output this edge regarless of + // wheter or not we know v-in yet. ok i;ll try this now: + tmpunderedges[under_edge_count].v = (byte)vout; + tmpunderedges[under_edge_count].p = (byte)underplanescount; + tmpunderedges[under_edge_count].ea = -1; + coplanaredge = under_edge_count; + under_edge_count++; + + if (vin != -1) + { + // we previously processed an edge where we came under + // now we know about vout as well + + // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! + } + + } + else if (vertflag[edge0.v].planetest == (0) && vertflag[edge1.v].planetest == (2)) + { + // first is coplanar 2nd is over + + edgeflag[e0].undermap = -1; + vout = vertflag[edge0.v].undermap; + // I hate this but i have to make sure part of this face is UNDER before ouputting this vert + int k = estart; + Debug.Assert(edge0.p == currentplane); + while (!((planeside & 1) != 0) && k < convex.edges.Count && convex.edges[k].p == edge0.p) + { + planeside |= vertflag[convex.edges[k].v].planetest; + k++; + } + if ((planeside & 1) != 0) + { + tmpunderedges[under_edge_count].v = (byte)vout; + tmpunderedges[under_edge_count].p = (byte)underplanescount; + tmpunderedges[under_edge_count].ea = -1; + coplanaredge = under_edge_count; // hmmm should make a note of the edge # for later on + under_edge_count++; + + } + } + else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (1)) + { + // first is over next is under + // new vertex!!! + Debug.Assert(vin == -1); + if (e0 < edge0.ea) + { + Plane p0 = convex.facets[edge0.p]; + Plane pa = convex.facets[edgea.p]; + createdverts.Add(ThreePlaneIntersection(p0, pa, slice)); + //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])); + //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]))); + vin = vertcountunder++; + } + else + { + // find the new vertex that was created by edge[edge0.ea] + int nea = edgeflag[edge0.ea].undermap; + Debug.Assert(tmpunderedges[nea].p == tmpunderedges[nea + 1].p); + vin = tmpunderedges[nea + 1].v; + Debug.Assert(vin < vertcountunder); + Debug.Assert(vin >= vertcountunderold); // for debugging only + } + if (vout != -1) + { + // we previously processed an edge where we went over + // now we know vin too + // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! + } + // output edge + tmpunderedges[under_edge_count].v = (byte)vin; + tmpunderedges[under_edge_count].p = (byte)underplanescount; + edgeflag[e0].undermap = (short)under_edge_count; + if (e0 > edge0.ea) + { + Debug.Assert(edgeflag[edge0.ea].undermap != -1); + // connect the neighbors + tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; + tmpunderedges[edgeflag[edge0.ea].undermap].ea = (short)under_edge_count; + } + Debug.Assert(edgeflag[e0].undermap == under_edge_count); + under_edge_count++; + } + else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (0)) + { + // first is over next is coplanar + + edgeflag[e0].undermap = -1; + vin = vertflag[edge1.v].undermap; + Debug.Assert(vin != -1); + if (vout != -1) + { + // we previously processed an edge where we came under + // now we know both endpoints + // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! + } + + } + else + { + Debug.Assert(false); + } + + + e0 = e1; + e1++; // do the modulo at the beginning of the loop + + } while (e0 != estart); + e0 = enextface; + if ((planeside & 1) != 0) + { + planeflag[currentplane].undermap = (byte)underplanescount; + tmpunderplanes[underplanescount] = convex.facets[currentplane]; + underplanescount++; + } + else + { + planeflag[currentplane].undermap = 0; + } + if (vout >= 0 && (planeside & 1) != 0) + { + Debug.Assert(vin >= 0); + Debug.Assert(coplanaredge >= 0); + Debug.Assert(coplanaredge != 511); + coplanaredges[coplanaredges_num].ea = (ushort)coplanaredge; + coplanaredges[coplanaredges_num].v0 = (byte)vin; + coplanaredges[coplanaredges_num].v1 = (byte)vout; + coplanaredges_num++; + } + } + + // add the new plane to the mix: + if (coplanaredges_num > 0) + { + tmpunderplanes[underplanescount++] = slice; + } + for (i = 0; i < coplanaredges_num - 1; i++) + { + if (coplanaredges[i].v1 != coplanaredges[i + 1].v0) + { + int j = 0; + for (j = i + 2; j < coplanaredges_num; j++) + { + if (coplanaredges[i].v1 == coplanaredges[j].v0) + { + Coplanar tmp = coplanaredges[i + 1]; + coplanaredges[i + 1] = coplanaredges[j]; + coplanaredges[j] = tmp; + break; + } + } + if (j >= coplanaredges_num) + { + Debug.Assert(j < coplanaredges_num); + return null; + } + } + } + + ConvexH punder = new ConvexH(vertcountunder, under_edge_count + coplanaredges_num, underplanescount); + ConvexH under = punder; + + { + int k = 0; + for (i = 0; i < convex.vertices.Count; i++) + { + if (vertflag[i].planetest != (2)) + { + under.vertices[k++] = convex.vertices[i]; + } + } + i = 0; + while (k < vertcountunder) + { + under.vertices[k++] = createdverts[i++]; + } + Debug.Assert(i == createdverts.Count); + } + + for (i = 0; i < coplanaredges_num; i++) + { + ConvexH.HalfEdge edge = under.edges[under_edge_count + i]; + edge.p = (byte)(underplanescount - 1); + edge.ea = (short)coplanaredges[i].ea; + edge.v = (byte)coplanaredges[i].v0; + under.edges[under_edge_count + i] = edge; + + tmpunderedges[coplanaredges[i].ea].ea = (short)(under_edge_count + i); + } + + under.edges = new List(tmpunderedges); + under.facets = new List(tmpunderplanes); + return punder; + } + + public static ConvexH ConvexHDup(ConvexH src) + { + ConvexH dst = new ConvexH(src.vertices.Count, src.edges.Count, src.facets.Count); + dst.vertices = new List(src.vertices.Count); + foreach (float3 f in src.vertices) + dst.vertices.Add(new float3(f)); + dst.edges = new List(src.edges.Count); + foreach (ConvexH.HalfEdge e in src.edges) + dst.edges.Add(new ConvexH.HalfEdge(e)); + dst.facets = new List(src.facets.Count); + foreach (Plane p in src.facets) + dst.facets.Add(new Plane(p)); + return dst; + } + + public static int candidateplane(List planes, int planes_count, ConvexH convex, float epsilon) + { + int p = 0; + float md = 0; + int i; + for (i = 0; i < planes_count; i++) + { + float d = 0; + for (int j = 0; j < convex.vertices.Count; j++) + { + d = Math.Max(d, float3.dot(convex.vertices[j], planes[i].normal) + planes[i].dist); + } + if (i == 0 || d > md) + { + p = i; + md = d; + } + } + return (md > epsilon) ? p : -1; + } + + public static float3 orth(float3 v) + { + float3 a = float3.cross(v, new float3(0f, 0f, 1f)); + float3 b = float3.cross(v, new float3(0f, 1f, 0f)); + return float3.normalize((float3.magnitude(a) > float3.magnitude(b)) ? a : b); + } + + public static int maxdir(List p, int count, float3 dir) + { + Debug.Assert(count != 0); + int m = 0; + float currDotm = float3.dot(p[0], dir); + for (int i = 1; i < count; i++) + { + float currDoti = float3.dot(p[i], dir); + if (currDoti > currDotm) + { + currDotm = currDoti; + m = i; + } + } + return m; + } + + public static int maxdirfiltered(List p, int count, float3 dir, byte[] allow) + { + //Debug.Assert(count != 0); + int m = 0; + float currDotm = float3.dot(p[0], dir); + float currDoti; + + while (allow[m] == 0) + m++; + + for (int i = 1; i < count; i++) + { + if (allow[i] != 0) + { + currDoti = float3.dot(p[i], dir); + if (currDoti > currDotm) + { + currDotm = currDoti; + m = i; + } + } + } + //Debug.Assert(m != -1); + return m; + } + + public static int maxdirsterid(List p, int count, float3 dir, byte[] allow) + { + int m = -1; + while (m == -1) + { + m = maxdirfiltered(p, count, dir, allow); + if (allow[m] == 3) + return m; + float3 u = orth(dir); + float3 v = float3.cross(u, dir); + int ma = -1; + for (float x = 0.0f; x <= 360.0f; x += 45.0f) + { + int mb; + { + float s = (float)Math.Sin((3.14159264f / 180.0f) * (x)); + float c = (float)Math.Cos((3.14159264f / 180.0f) * (x)); + mb = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow); + } + if (ma == m && mb == m) + { + allow[m] = 3; + return m; + } + if (ma != -1 && ma != mb) // Yuck - this is really ugly + { + int mc = ma; + for (float xx = x - 40.0f; xx <= x; xx += 5.0f) + { + float s = (float)Math.Sin((3.14159264f / 180.0f) * (xx)); + float c = (float)Math.Cos((3.14159264f / 180.0f) * (xx)); + int md = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow); + if (mc == m && md == m) + { + allow[m] = 3; + return m; + } + mc = md; + } + } + ma = mb; + } + allow[m] = 0; + m = -1; + } + + Debug.Assert(false); + return m; + } + + public static int4 FindSimplex(List verts, byte[] allow) + { + float3[] basis = new float3[3]; + basis[0] = new float3(0.01f, 0.02f, 1.0f); + int p0 = maxdirsterid(verts, verts.Count, basis[0], allow); + int p1 = maxdirsterid(verts, verts.Count, -basis[0], allow); + basis[0] = verts[p0] - verts[p1]; + if (p0 == p1 || basis[0] == new float3(0, 0, 0)) + return new int4(-1, -1, -1, -1); + basis[1] = float3.cross(new float3(1, 0.02f, 0), basis[0]); + basis[2] = float3.cross(new float3(-0.02f, 1, 0), basis[0]); + basis[1] = float3.normalize((float3.magnitude(basis[1]) > float3.magnitude(basis[2])) ? basis[1] : basis[2]); + int p2 = maxdirsterid(verts, verts.Count, basis[1], allow); + if (p2 == p0 || p2 == p1) + { + p2 = maxdirsterid(verts, verts.Count, -basis[1], allow); + } + if (p2 == p0 || p2 == p1) + return new int4(-1, -1, -1, -1); + basis[1] = verts[p2] - verts[p0]; + basis[2] = float3.normalize(float3.cross(basis[1], basis[0])); + int p3 = maxdirsterid(verts, verts.Count, basis[2], allow); + if (p3 == p0 || p3 == p1 || p3 == p2) + p3 = maxdirsterid(verts, verts.Count, -basis[2], allow); + if (p3 == p0 || p3 == p1 || p3 == p2) + return new int4(-1, -1, -1, -1); + Debug.Assert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3)); + if (float3.dot(verts[p3] - verts[p0], float3.cross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0) + { + Swap(ref p2, ref p3); + } + return new int4(p0, p1, p2, p3); + } + + public static float GetDist(float px, float py, float pz, float3 p2) + { + float dx = px - p2.x; + float dy = py - p2.y; + float dz = pz - p2.z; + + return dx * dx + dy * dy + dz * dz; + } + + public static void ReleaseHull(PHullResult result) + { + if (result.Indices != null) + result.Indices = null; + if (result.Vertices != null) + result.Vertices = null; + } + + public static int calchullgen(List verts, int vlimit, List tris) + { + if (verts.Count < 4) + return 0; + if (vlimit == 0) + vlimit = 1000000000; + int j; + float3 bmin = new float3(verts[0]); + float3 bmax = new float3(verts[0]); + List isextreme = new List(verts.Count); + byte[] allow = new byte[verts.Count]; + for (j = 0; j < verts.Count; j++) + { + allow[j] = 1; + isextreme.Add(0); + bmin = float3.VectorMin(bmin, verts[j]); + bmax = float3.VectorMax(bmax, verts[j]); + } + float epsilon = float3.magnitude(bmax - bmin) * 0.001f; + + int4 p = FindSimplex(verts, allow); + if (p.x == -1) // simplex failed + return 0; + + float3 center = (verts[p[0]] + verts[p[1]] + verts[p[2]] + verts[p[3]]) / 4.0f; // a valid interior point + HullTriangle t0 = new HullTriangle(p[2], p[3], p[1], tris); + t0.n = new int3(2, 3, 1); + HullTriangle t1 = new HullTriangle(p[3], p[2], p[0], tris); + t1.n = new int3(3, 2, 0); + HullTriangle t2 = new HullTriangle(p[0], p[1], p[3], tris); + t2.n = new int3(0, 1, 3); + HullTriangle t3 = new HullTriangle(p[1], p[0], p[2], tris); + t3.n = new int3(1, 0, 2); + isextreme[p[0]] = isextreme[p[1]] = isextreme[p[2]] = isextreme[p[3]] = 1; + checkit(t0, tris); + checkit(t1, tris); + checkit(t2, tris); + checkit(t3, tris); + + for (j = 0; j < tris.Count; j++) + { + HullTriangle t = tris[j]; + Debug.Assert((object)t != null); + Debug.Assert(t.vmax < 0); + float3 n = TriNormal(verts[(t)[0]], verts[(t)[1]], verts[(t)[2]]); + t.vmax = maxdirsterid(verts, verts.Count, n, allow); + t.rise = float3.dot(n, verts[t.vmax] - verts[(t)[0]]); + } + HullTriangle te; + vlimit -= 4; + while (vlimit > 0 && (te = extrudable(epsilon, tris)) != null) + { + int3 ti = te; + int v = te.vmax; + Debug.Assert(isextreme[v] == 0); // wtf we've already done this vertex + isextreme[v] = 1; + //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already + j = tris.Count; + while (j-- != 0) + { + if (tris.Count <= j || (object)tris[j] == null) + continue; + int3 t = tris[j]; + if (above(verts, t, verts[v], 0.01f * epsilon)) + { + extrude(tris[j], v, tris); + } + } + // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle + j = tris.Count; + while (j-- != 0) + { + if (tris.Count <= j || (object)tris[j] == null) + continue; + if (!hasvert(tris[j], v)) + break; + int3 nt = tris[j]; + if (above(verts, nt, center, 0.01f * epsilon) || float3.magnitude(float3.cross(verts[nt[1]] - verts[nt[0]], verts[nt[2]] - verts[nt[1]])) < epsilon * epsilon * 0.1f) + { + HullTriangle nb = tris[tris[j].n[0]]; + Debug.Assert(nb != null); + Debug.Assert(!hasvert(nb, v)); + Debug.Assert(nb.id < j); + extrude(nb, v, tris); + j = tris.Count; + } + } + j = tris.Count; + while (j-- != 0) + { + HullTriangle t = tris[j]; + if (t == null) + continue; + if (t.vmax >= 0) + break; + float3 n = TriNormal(verts[(t)[0]], verts[(t)[1]], verts[(t)[2]]); + t.vmax = maxdirsterid(verts, verts.Count, n, allow); + if (isextreme[t.vmax] != 0) + { + t.vmax = -1; // already done that vertex - algorithm needs to be able to terminate. + } + else + { + t.rise = float3.dot(n, verts[t.vmax] - verts[(t)[0]]); + } + } + vlimit--; + } + return 1; + } + + public static bool calchull(List verts, out List tris_out, int vlimit, List tris) + { + tris_out = null; + + int rc = calchullgen(verts, vlimit, tris); + if (rc == 0) + return false; + List ts = new List(); + for (int i = 0; i < tris.Count; i++) + { + if ((object)tris[i] != null) + { + for (int j = 0; j < 3; j++) + ts.Add((tris[i])[j]); + tris[i] = null; + } + } + + tris_out = ts; + tris.Clear(); + return true; + } + + public static int calchullpbev(List verts, int vlimit, out List planes, float bevangle, List tris) + { + int i; + int j; + planes = new List(); + int rc = calchullgen(verts, vlimit, tris); + if (rc == 0) + return 0; + for (i = 0; i < tris.Count; i++) + { + if (tris[i] != null) + { + Plane p = new Plane(); + HullTriangle t = tris[i]; + p.normal = TriNormal(verts[(t)[0]], verts[(t)[1]], verts[(t)[2]]); + p.dist = -float3.dot(p.normal, verts[(t)[0]]); + planes.Add(p); + for (j = 0; j < 3; j++) + { + if (t.n[j] < t.id) + continue; + HullTriangle s = tris[t.n[j]]; + float3 snormal = TriNormal(verts[(s)[0]], verts[(s)[1]], verts[(s)[2]]); + if (float3.dot(snormal, p.normal) >= Math.Cos(bevangle * (3.14159264f / 180.0f))) + continue; + float3 n = float3.normalize(snormal + p.normal); + planes.Add(new Plane(n, -float3.dot(n, verts[maxdir(verts, verts.Count, n)]))); + } + } + } + + tris.Clear(); + return 1; + } + + public static int overhull(List planes, List verts, int maxplanes, out List verts_out, out List faces_out, float inflate) + { + verts_out = null; + faces_out = null; + + int i; + int j; + if (verts.Count < 4) + return 0; + maxplanes = Math.Min(maxplanes, planes.Count); + float3 bmin = new float3(verts[0]); + float3 bmax = new float3(verts[0]); + for (i = 0; i < verts.Count; i++) + { + bmin = float3.VectorMin(bmin, verts[i]); + bmax = float3.VectorMax(bmax, verts[i]); + } + // float diameter = magnitude(bmax-bmin); + // inflate *=diameter; // RELATIVE INFLATION + bmin -= new float3(inflate, inflate, inflate); + bmax += new float3(inflate, inflate, inflate); + for (i = 0; i < planes.Count; i++) + { + planes[i].dist -= inflate; + } + float3 emin = new float3(bmin); + float3 emax = new float3(bmax); + float epsilon = float3.magnitude(emax - emin) * 0.025f; + float planetestepsilon = float3.magnitude(emax - emin) * (0.001f); + // todo: add bounding cube planes to force bevel. or try instead not adding the diameter expansion ??? must think. + // ConvexH *convex = ConvexHMakeCube(bmin - float3(diameter,diameter,diameter),bmax+float3(diameter,diameter,diameter)); + ConvexH c = ConvexHMakeCube(new float3(bmin), new float3(bmax)); + int k; + while (maxplanes-- != 0 && (k = candidateplane(planes, planes.Count, c, epsilon)) >= 0) + { + ConvexH tmp = c; + c = ConvexHCrop(ref tmp, planes[k], planetestepsilon); + if (c == null) // might want to debug this case better!!! + { + c = tmp; + break; + } + if (AssertIntact(c, planetestepsilon) == false) // might want to debug this case better too!!! + { + c = tmp; + break; + } + tmp.edges = null; + tmp.facets = null; + tmp.vertices = null; + } + + Debug.Assert(AssertIntact(c, planetestepsilon)); + //return c; + //C++ TO C# CONVERTER TODO TASK: The memory management function 'malloc' has no equivalent in C#: + faces_out = new List(); //(int)malloc(sizeof(int) * (1 + c.facets.Count + c.edges.Count)); // new int[1+c->facets.count+c->edges.count]; + int faces_count_out = 0; + i = 0; + faces_out[faces_count_out++] = -1; + k = 0; + while (i < c.edges.Count) + { + j = 1; + while (j + i < c.edges.Count && c.edges[i].p == c.edges[i + j].p) + { + j++; + } + faces_out[faces_count_out++] = j; + while (j-- != 0) + { + faces_out[faces_count_out++] = c.edges[i].v; + i++; + } + k++; + } + faces_out[0] = k; // number of faces. + Debug.Assert(k == c.facets.Count); + Debug.Assert(faces_count_out == 1 + c.facets.Count + c.edges.Count); + verts_out = c.vertices; // new float3[c->vertices.count]; + int verts_count_out = c.vertices.Count; + for (i = 0; i < c.vertices.Count; i++) + { + verts_out[i] = new float3(c.vertices[i]); + } + + c.edges = null; + c.facets = null; + c.vertices = null; + return 1; + } + + public static int overhullv(List verts, int maxplanes, out List verts_out, out List faces_out, float inflate, float bevangle, int vlimit, List tris) + { + verts_out = null; + faces_out = null; + + if (verts.Count == 0) + return 0; + List planes = new List(); + int rc = calchullpbev(verts, vlimit, out planes, bevangle, tris); + if (rc == 0) + return 0; + return overhull(planes, verts, maxplanes, out verts_out, out faces_out, inflate); + } + + public static void addPoint(ref uint vcount, List p, float x, float y, float z) + { + p.Add(new float3(x, y, z)); + vcount++; + } + + public static bool ComputeHull(List vertices, ref PHullResult result, int vlimit, float inflate) + { + List tris = new List(); + List faces; + List verts_out; + + if (inflate == 0.0f) + { + List tris_out; + bool ret = calchull(vertices, out tris_out, vlimit, tris); + if (ret == false) + return false; + + result.Indices = tris_out; + result.Vertices = vertices; + return true; + } + else + { + int ret = overhullv(vertices, 35, out verts_out, out faces, inflate, 120.0f, vlimit, tris); + if (ret == 0) + return false; + + List tris2 = new List(); + int n = faces[0]; + int k = 1; + for (int i = 0; i < n; i++) + { + int pn = faces[k++]; + for (int j = 2; j < pn; j++) + tris2.Add(new int3(faces[k], faces[k + j - 1], faces[k + j])); + k += pn; + } + Debug.Assert(tris2.Count == faces.Count - 1 - (n * 3)); + + result.Indices = new List(tris2.Count * 3); + for (int i = 0; i < tris2.Count; i++) + { + result.Indices.Add(tris2[i].x); + result.Indices.Add(tris2[i].y); + result.Indices.Add(tris2[i].z); + } + result.Vertices = verts_out; + + return true; + } + } + + private static bool CleanupVertices(List svertices, out List vertices, float normalepsilon, out float3 scale) + { + const float EPSILON = 0.000001f; + + vertices = new List(); + scale = new float3(1f, 1f, 1f); + + if (svertices.Count == 0) + return false; + + uint vcount = 0; + + float[] recip = new float[3]; + + float[] bmin = { Single.MaxValue, Single.MaxValue, Single.MaxValue }; + float[] bmax = { Single.MinValue, Single.MinValue, Single.MinValue }; + + for (int i = 0; i < svertices.Count; i++) + { + float3 p = svertices[i]; + + for (int j = 0; j < 3; j++) + { + if (p[j] < bmin[j]) + bmin[j] = p[j]; + if (p[j] > bmax[j]) + bmax[j] = p[j]; + } + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + float3 center = new float3(); + + center.x = dx * 0.5f + bmin[0]; + center.y = dy * 0.5f + bmin[1]; + center.z = dz * 0.5f + bmin[2]; + + if (dx < EPSILON || dy < EPSILON || dz < EPSILON || svertices.Count < 3) + { + float len = Single.MaxValue; + + if (dx > EPSILON && dx < len) + len = dx; + if (dy > EPSILON && dy < len) + len = dy; + if (dz > EPSILON && dz < len) + len = dz; + + if (len == Single.MaxValue) + { + dx = dy = dz = 0.01f; // one centimeter + } + else + { + if (dx < EPSILON) // 1/5th the shortest non-zero edge. + dx = len * 0.05f; + if (dy < EPSILON) + dy = len * 0.05f; + if (dz < EPSILON) + dz = len * 0.05f; + } + + float x1 = center[0] - dx; + float x2 = center[0] + dx; + + float y1 = center[1] - dy; + float y2 = center[1] + dy; + + float z1 = center[2] - dz; + float z2 = center[2] + dz; + + addPoint(ref vcount, vertices, x1, y1, z1); + addPoint(ref vcount, vertices, x2, y1, z1); + addPoint(ref vcount, vertices, x2, y2, z1); + addPoint(ref vcount, vertices, x1, y2, z1); + addPoint(ref vcount, vertices, x1, y1, z2); + addPoint(ref vcount, vertices, x2, y1, z2); + addPoint(ref vcount, vertices, x2, y2, z2); + addPoint(ref vcount, vertices, x1, y2, z2); + + return true; // return cube + } + else + { + scale.x = dx; + scale.y = dy; + scale.z = dz; + + recip[0] = 1f / dx; + recip[1] = 1f / dy; + recip[2] = 1f / dz; + + center.x *= recip[0]; + center.y *= recip[1]; + center.z *= recip[2]; + } + + for (int i = 0; i < svertices.Count; i++) + { + float3 p = svertices[i]; + + float px = p[0]; + float py = p[1]; + float pz = p[2]; + + px = px * recip[0]; // normalize + py = py * recip[1]; // normalize + pz = pz * recip[2]; // normalize + + if (true) + { + int j; + + for (j = 0; j < vcount; j++) + { + float3 v = vertices[j]; + + float x = v[0]; + float y = v[1]; + float z = v[2]; + + float dx1 = Math.Abs(x - px); + float dy1 = Math.Abs(y - py); + float dz1 = Math.Abs(z - pz); + + if (dx1 < normalepsilon && dy1 < normalepsilon && dz1 < normalepsilon) + { + // ok, it is close enough to the old one + // now let us see if it is further from the center of the point cloud than the one we already recorded. + // in which case we keep this one instead. + float dist1 = GetDist(px, py, pz, center); + float dist2 = GetDist(v[0], v[1], v[2], center); + + if (dist1 > dist2) + { + v.x = px; + v.y = py; + v.z = pz; + } + + break; + } + } + + if (j == vcount) + { + float3 dest = new float3(px, py, pz); + vertices.Add(dest); + vcount++; + } + } + } + + // ok..now make sure we didn't prune so many vertices it is now invalid. + if (true) + { + float[] bmin2 = { Single.MaxValue, Single.MaxValue, Single.MaxValue }; + float[] bmax2 = { Single.MinValue, Single.MinValue, Single.MinValue }; + + for (int i = 0; i < vcount; i++) + { + float3 p = vertices[i]; + for (int j = 0; j < 3; j++) + { + if (p[j] < bmin2[j]) + bmin2[j] = p[j]; + if (p[j] > bmax2[j]) + bmax2[j] = p[j]; + } + } + + float dx2 = bmax2[0] - bmin2[0]; + float dy2 = bmax2[1] - bmin2[1]; + float dz2 = bmax2[2] - bmin2[2]; + + if (dx2 < EPSILON || dy2 < EPSILON || dz2 < EPSILON || vcount < 3) + { + float cx = dx2 * 0.5f + bmin2[0]; + float cy = dy2 * 0.5f + bmin2[1]; + float cz = dz2 * 0.5f + bmin2[2]; + + float len = Single.MaxValue; + + if (dx2 >= EPSILON && dx2 < len) + len = dx2; + if (dy2 >= EPSILON && dy2 < len) + len = dy2; + if (dz2 >= EPSILON && dz2 < len) + len = dz2; + + if (len == Single.MaxValue) + { + dx2 = dy2 = dz2 = 0.01f; // one centimeter + } + else + { + if (dx2 < EPSILON) // 1/5th the shortest non-zero edge. + dx2 = len * 0.05f; + if (dy2 < EPSILON) + dy2 = len * 0.05f; + if (dz2 < EPSILON) + dz2 = len * 0.05f; + } + + float x1 = cx - dx2; + float x2 = cx + dx2; + + float y1 = cy - dy2; + float y2 = cy + dy2; + + float z1 = cz - dz2; + float z2 = cz + dz2; + + vcount = 0; // add box + + addPoint(ref vcount, vertices, x1, y1, z1); + addPoint(ref vcount, vertices, x2, y1, z1); + addPoint(ref vcount, vertices, x2, y2, z1); + addPoint(ref vcount, vertices, x1, y2, z1); + addPoint(ref vcount, vertices, x1, y1, z2); + addPoint(ref vcount, vertices, x2, y1, z2); + addPoint(ref vcount, vertices, x2, y2, z2); + addPoint(ref vcount, vertices, x1, y2, z2); + + return true; + } + } + + return true; + } + + private static void BringOutYourDead(List verts, out List overts, List indices) + { + int[] used = new int[verts.Count]; + int ocount = 0; + + overts = new List(); + + for (int i = 0; i < indices.Count; i++) + { + int v = indices[i]; // original array index + + Debug.Assert(v >= 0 && v < verts.Count); + + if (used[v] != 0) // if already remapped + { + indices[i] = used[v] - 1; // index to new array + } + else + { + indices[i] = ocount; // new index mapping + + overts.Add(verts[v]); // copy old vert to new vert array + + ocount++; // increment output vert count + + Debug.Assert(ocount >= 0 && ocount <= verts.Count); + + used[v] = ocount; // assign new index remapping + } + } + } + + public static HullError CreateConvexHull(HullDesc desc, ref HullResult result) + { + HullError ret = HullError.QE_FAIL; + + PHullResult hr = new PHullResult(); + + uint vcount = (uint)desc.Vertices.Count; + if (vcount < 8) + vcount = 8; + + List vsource; + float3 scale = new float3(); + + bool ok = CleanupVertices(desc.Vertices, out vsource, desc.NormalEpsilon, out scale); // normalize point cloud, remove duplicates! + + if (ok) + { + if (true) // scale vertices back to their original size. + { + for (int i = 0; i < vsource.Count; i++) + { + float3 v = vsource[i]; + v.x *= scale[0]; + v.y *= scale[1]; + v.z *= scale[2]; + } + } + + float skinwidth = 0; + if (desc.HasHullFlag(HullFlag.QF_SKIN_WIDTH)) + skinwidth = desc.SkinWidth; + + ok = ComputeHull(vsource, ref hr, (int)desc.MaxVertices, skinwidth); + + if (ok) + { + List vscratch; + BringOutYourDead(hr.Vertices, out vscratch, hr.Indices); + + ret = HullError.QE_OK; + + if (desc.HasHullFlag(HullFlag.QF_TRIANGLES)) // if he wants the results as triangle! + { + result.Polygons = false; + result.Indices = hr.Indices; + result.OutputVertices = vscratch; + } + else + { + result.Polygons = true; + result.OutputVertices = vscratch; + + if (true) + { + List source = hr.Indices; + List dest = new List(); + for (int i = 0; i < hr.Indices.Count / 3; i++) + { + dest.Add(3); + dest.Add(source[i * 3 + 0]); + dest.Add(source[i * 3 + 1]); + dest.Add(source[i * 3 + 2]); + } + + result.Indices = dest; + } + } + } + } + + return ret; + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt b/OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt new file mode 100644 index 0000000..714ae89 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt @@ -0,0 +1,28 @@ +ConvexDecompositionDotNet +------------------------- + +The MIT License + +Copyright (c) 2010 Intel Corporation. +All rights reserved. + +Based on the convexdecomposition library from + by John W. Ratcliff and Stan Melax. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs new file mode 100644 index 0000000..d099676 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs @@ -0,0 +1,99 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class Plane + { + public float3 normal = new float3(); + public float dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + + public Plane(float3 n, float d) + { + normal = new float3(n); + dist = d; + } + + public Plane(Plane p) + { + normal = new float3(p.normal); + dist = p.dist; + } + + public Plane() + { + dist = 0; + } + + public void Transform(float3 position, Quaternion orientation) + { + // Transforms the plane to the space defined by the + // given position/orientation + float3 newNormal = Quaternion.Inverse(orientation) * normal; + float3 origin = Quaternion.Inverse(orientation) * (-normal * dist - position); + + normal = newNormal; + dist = -float3.dot(newNormal, origin); + } + + public override int GetHashCode() + { + return normal.GetHashCode() ^ dist.GetHashCode(); + } + + public override bool Equals(object obj) + { + Plane p = obj as Plane; + if (p == null) + return false; + + return this == p; + } + + public static bool operator ==(Plane a, Plane b) + { + return (a.normal == b.normal && a.dist == b.dist); + } + + public static bool operator !=(Plane a, Plane b) + { + return !(a == b); + } + + public static Plane PlaneFlip(Plane plane) + { + return new Plane(-plane.normal, -plane.dist); + } + + public static bool coplanar(Plane a, Plane b) + { + return (a == b || a == PlaneFlip(b)); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs new file mode 100644 index 0000000..31f0182 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs @@ -0,0 +1,211 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public enum PlaneTriResult : int + { + PTR_FRONT, + PTR_BACK, + PTR_SPLIT + } + + public static class PlaneTri + { + private static float DistToPt(float3 p, float4 plane) + { + return p.x * plane.x + p.y * plane.y + p.z * plane.z + plane.w; + } + + private static PlaneTriResult getSidePlane(float3 p, float4 plane, float epsilon) + { + float d = DistToPt(p, plane); + + if ((d + epsilon) > 0f) + return PlaneTriResult.PTR_FRONT; // it is 'in front' within the provided epsilon value. + + return PlaneTriResult.PTR_BACK; + } + + private static void add(float3 p, float3[] dest, ref int pcount) + { + dest[pcount++] = new float3(p); + Debug.Assert(pcount <= 4); + } + + // assumes that the points are on opposite sides of the plane! + private static void intersect(float3 p1, float3 p2, float3 split, float4 plane) + { + float dp1 = DistToPt(p1, plane); + float[] dir = new float[3]; + + dir[0] = p2[0] - p1[0]; + dir[1] = p2[1] - p1[1]; + dir[2] = p2[2] - p1[2]; + + float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2]; + float dot2 = dp1 - plane[3]; + + float t = -(plane[3] + dot2) / dot1; + + split.x = (dir[0] * t) + p1[0]; + split.y = (dir[1] * t) + p1[1]; + split.z = (dir[2] * t) + p1[2]; + } + + public static PlaneTriResult planeTriIntersection(float4 plane, FaceTri triangle, float epsilon, ref float3[] front, out int fcount, ref float3[] back, out int bcount) + { + fcount = 0; + bcount = 0; + + // get the three vertices of the triangle. + float3 p1 = triangle.P1; + float3 p2 = triangle.P2; + float3 p3 = triangle.P3; + + PlaneTriResult r1 = getSidePlane(p1, plane, epsilon); // compute the side of the plane each vertex is on + PlaneTriResult r2 = getSidePlane(p2, plane, epsilon); + PlaneTriResult r3 = getSidePlane(p3, plane, epsilon); + + if (r1 == r2 && r1 == r3) // if all three vertices are on the same side of the plane. + { + if (r1 == PlaneTriResult.PTR_FRONT) // if all three are in front of the plane, then copy to the 'front' output triangle. + { + add(p1, front, ref fcount); + add(p2, front, ref fcount); + add(p3, front, ref fcount); + } + else + { + add(p1, back, ref bcount); // if all three are in 'back' then copy to the 'back' output triangle. + add(p2, back, ref bcount); + add(p3, back, ref bcount); + } + return r1; // if all three points are on the same side of the plane return result + } + + // ok.. we need to split the triangle at the plane. + + // First test ray segment P1 to P2 + if (r1 == r2) // if these are both on the same side... + { + if (r1 == PlaneTriResult.PTR_FRONT) + { + add(p1, front, ref fcount); + add(p2, front, ref fcount); + } + else + { + add(p1, back, ref bcount); + add(p2, back, ref bcount); + } + } + else + { + float3 split = new float3(); + intersect(p1, p2, split, plane); + + if (r1 == PlaneTriResult.PTR_FRONT) + { + + add(p1, front, ref fcount); + add(split, front, ref fcount); + + add(split, back, ref bcount); + add(p2, back, ref bcount); + + } + else + { + add(p1, back, ref bcount); + add(split, back, ref bcount); + + add(split, front, ref fcount); + add(p2, front, ref fcount); + } + + } + + // Next test ray segment P2 to P3 + if (r2 == r3) // if these are both on the same side... + { + if (r3 == PlaneTriResult.PTR_FRONT) + { + add(p3, front, ref fcount); + } + else + { + add(p3, back, ref bcount); + } + } + else + { + float3 split = new float3(); // split the point + intersect(p2, p3, split, plane); + + if (r3 == PlaneTriResult.PTR_FRONT) + { + add(split, front, ref fcount); + add(split, back, ref bcount); + + add(p3, front, ref fcount); + } + else + { + add(split, front, ref fcount); + add(split, back, ref bcount); + + add(p3, back, ref bcount); + } + } + + // Next test ray segment P3 to P1 + if (r3 != r1) // if these are both on the same side... + { + float3 split = new float3(); // split the point + intersect(p3, p1, split, plane); + + if (r1 == PlaneTriResult.PTR_FRONT) + { + add(split, front, ref fcount); + add(split, back, ref bcount); + } + else + { + add(split, front, ref fcount); + add(split, back, ref bcount); + } + } + + return PlaneTriResult.PTR_SPLIT; + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4285e8c --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ConvexDecompositionDotNet")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Intel Corporation")] +[assembly: AssemblyProduct("ConvexDecompositionDotNet")] +[assembly: AssemblyCopyright("Copyright © Intel Corporation 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2a1c9467-1a17-4c8d-bf9f-4b4d86dd0cbb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs new file mode 100644 index 0000000..0ba8f17 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs @@ -0,0 +1,209 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class Quaternion : float4 + { + public Quaternion() + { + x = y = z = 0.0f; + w = 1.0f; + } + + public Quaternion(float3 v, float t) + { + v = float3.normalize(v); + w = (float)Math.Cos(t / 2.0f); + v = v * (float)Math.Sin(t / 2.0f); + x = v.x; + y = v.y; + z = v.z; + } + + public Quaternion(float _x, float _y, float _z, float _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + + public float angle() + { + return (float)Math.Acos(w) * 2.0f; + } + + public float3 axis() + { + float3 a = new float3(x, y, z); + if (Math.Abs(angle()) < 0.0000001f) + return new float3(1f, 0f, 0f); + return a * (1 / (float)Math.Sin(angle() / 2.0f)); + } + + public float3 xdir() + { + return new float3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y)); + } + + public float3 ydir() + { + return new float3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x)); + } + + public float3 zdir() + { + return new float3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y)); + } + + public float3x3 getmatrix() + { + return new float3x3(xdir(), ydir(), zdir()); + } + + public static implicit operator float3x3(Quaternion q) + { + return q.getmatrix(); + } + + public static Quaternion operator *(Quaternion a, Quaternion b) + { + Quaternion c = new Quaternion(); + c.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z; + c.x = a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y; + c.y = a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x; + c.z = a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w; + return c; + } + + public static float3 operator *(Quaternion q, float3 v) + { + // The following is equivalent to: + //return (q.getmatrix() * v); + float qx2 = q.x * q.x; + float qy2 = q.y * q.y; + float qz2 = q.z * q.z; + + float qxqy = q.x * q.y; + float qxqz = q.x * q.z; + float qxqw = q.x * q.w; + float qyqz = q.y * q.z; + float qyqw = q.y * q.w; + float qzqw = q.z * q.w; + return new float3((1 - 2 * (qy2 + qz2)) * v.x + (2 * (qxqy - qzqw)) * v.y + (2 * (qxqz + qyqw)) * v.z, (2 * (qxqy + qzqw)) * v.x + (1 - 2 * (qx2 + qz2)) * v.y + (2 * (qyqz - qxqw)) * v.z, (2 * (qxqz - qyqw)) * v.x + (2 * (qyqz + qxqw)) * v.y + (1 - 2 * (qx2 + qy2)) * v.z); + } + + public static Quaternion operator +(Quaternion a, Quaternion b) + { + return new Quaternion(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); + } + + public static Quaternion operator *(Quaternion a, float b) + { + return new Quaternion(a.x *b, a.y *b, a.z *b, a.w *b); + } + + public static Quaternion normalize(Quaternion a) + { + float m = (float)Math.Sqrt(a.w * a.w + a.x * a.x + a.y * a.y + a.z * a.z); + if (m < 0.000000001f) + { + a.w = 1; + a.x = a.y = a.z = 0; + return a; + } + return a * (1f / m); + } + + public static float dot(Quaternion a, Quaternion b) + { + return (a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z); + } + + public static Quaternion slerp(Quaternion a, Quaternion b, float interp) + { + if (dot(a, b) < 0.0) + { + a.w = -a.w; + a.x = -a.x; + a.y = -a.y; + a.z = -a.z; + } + float d = dot(a, b); + if (d >= 1.0) + { + return a; + } + float theta = (float)Math.Acos(d); + if (theta == 0.0f) + { + return (a); + } + return a * ((float)Math.Sin(theta - interp * theta) / (float)Math.Sin(theta)) + b * ((float)Math.Sin(interp * theta) / (float)Math.Sin(theta)); + } + + public static Quaternion Interpolate(Quaternion q0, Quaternion q1, float alpha) + { + return slerp(q0, q1, alpha); + } + + public static Quaternion Inverse(Quaternion q) + { + return new Quaternion(-q.x, -q.y, -q.z, q.w); + } + + public static Quaternion YawPitchRoll(float yaw, float pitch, float roll) + { + roll *= (3.14159264f / 180.0f); + yaw *= (3.14159264f / 180.0f); + pitch *= (3.14159264f / 180.0f); + return new Quaternion(new float3(0.0f, 0.0f, 1.0f), yaw) * new Quaternion(new float3(1.0f, 0.0f, 0.0f), pitch) * new Quaternion(new float3(0.0f, 1.0f, 0.0f), roll); + } + + public static float Yaw(Quaternion q) + { + float3 v = q.ydir(); + return (v.y == 0.0 && v.x == 0.0) ? 0.0f : (float)Math.Atan2(-v.x, v.y) * (180.0f / 3.14159264f); + } + + public static float Pitch(Quaternion q) + { + float3 v = q.ydir(); + return (float)Math.Atan2(v.z, Math.Sqrt(v.x * v.x + v.y * v.y)) * (180.0f / 3.14159264f); + } + + public static float Roll(Quaternion q) + { + q = new Quaternion(new float3(0.0f, 0.0f, 1.0f), -Yaw(q) * (3.14159264f / 180.0f)) * q; + q = new Quaternion(new float3(1.0f, 0.0f, 0.0f), -Pitch(q) * (3.14159264f / 180.0f)) * q; + return (float)Math.Atan2(-q.xdir().z, q.xdir().x) * (180.0f / 3.14159264f); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt b/OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt new file mode 100644 index 0000000..fc53ae7 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt @@ -0,0 +1,7 @@ +ConvexDecompositionDotNet +========================= + +A C# port of the ConvexDecomposition library by John W. Ratcliff and Stan Melax. +The original C++ version is available at . +See the blog post at +for a thorough explanation of generating convex hulls from concave meshes. diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs new file mode 100644 index 0000000..9f06a9a --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs @@ -0,0 +1,265 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class Rect3d + { + public float[] mMin = new float[3]; + public float[] mMax = new float[3]; + + public Rect3d() + { + } + + public Rect3d(float[] bmin, float[] bmax) + { + mMin[0] = bmin[0]; + mMin[1] = bmin[1]; + mMin[2] = bmin[2]; + + mMax[0] = bmax[0]; + mMax[1] = bmax[1]; + mMax[2] = bmax[2]; + } + + public void SetMin(float[] bmin) + { + mMin[0] = bmin[0]; + mMin[1] = bmin[1]; + mMin[2] = bmin[2]; + } + + public void SetMax(float[] bmax) + { + mMax[0] = bmax[0]; + mMax[1] = bmax[1]; + mMax[2] = bmax[2]; + } + + public void SetMin(float x, float y, float z) + { + mMin[0] = x; + mMin[1] = y; + mMin[2] = z; + } + + public void SetMax(float x, float y, float z) + { + mMax[0] = x; + mMax[1] = y; + mMax[2] = z; + } + } + + public static class SplitPlane + { + public static bool computeSplitPlane(List vertices, List indices, ref float4 plane) + { + float[] bmin = { Single.MaxValue, Single.MaxValue, Single.MaxValue }; + float[] bmax = { Single.MinValue, Single.MinValue, Single.MinValue }; + + for (int i = 0; i < vertices.Count; i++) + { + float3 p = vertices[i]; + + if (p[0] < bmin[0]) + bmin[0] = p[0]; + if (p[1] < bmin[1]) + bmin[1] = p[1]; + if (p[2] < bmin[2]) + bmin[2] = p[2]; + + if (p[0] > bmax[0]) + bmax[0] = p[0]; + if (p[1] > bmax[1]) + bmax[1] = p[1]; + if (p[2] > bmax[2]) + bmax[2] = p[2]; + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + float laxis = dx; + + int axis = 0; + + if (dy > dx) + { + axis = 1; + laxis = dy; + } + + if (dz > dx && dz > dy) + { + axis = 2; + laxis = dz; + } + + float[] p1 = new float[3]; + float[] p2 = new float[3]; + float[] p3 = new float[3]; + + p3[0] = p2[0] = p1[0] = bmin[0] + dx * 0.5f; + p3[1] = p2[1] = p1[1] = bmin[1] + dy * 0.5f; + p3[2] = p2[2] = p1[2] = bmin[2] + dz * 0.5f; + + Rect3d b = new Rect3d(bmin, bmax); + + Rect3d b1 = new Rect3d(); + Rect3d b2 = new Rect3d(); + + splitRect(axis, b, b1, b2, p1); + + switch (axis) + { + case 0: + p2[1] = bmin[1]; + p2[2] = bmin[2]; + + if (dz > dy) + { + p3[1] = bmax[1]; + p3[2] = bmin[2]; + } + else + { + p3[1] = bmin[1]; + p3[2] = bmax[2]; + } + + break; + case 1: + p2[0] = bmin[0]; + p2[2] = bmin[2]; + + if (dx > dz) + { + p3[0] = bmax[0]; + p3[2] = bmin[2]; + } + else + { + p3[0] = bmin[0]; + p3[2] = bmax[2]; + } + + break; + case 2: + p2[0] = bmin[0]; + p2[1] = bmin[1]; + + if (dx > dy) + { + p3[0] = bmax[0]; + p3[1] = bmin[1]; + } + else + { + p3[0] = bmin[0]; + p3[1] = bmax[1]; + } + + break; + } + + computePlane(p1, p2, p3, plane); + + return true; + } + + internal static void computePlane(float[] A, float[] B, float[] C, float4 plane) + { + float vx = (B[0] - C[0]); + float vy = (B[1] - C[1]); + float vz = (B[2] - C[2]); + + float wx = (A[0] - B[0]); + float wy = (A[1] - B[1]); + float wz = (A[2] - B[2]); + + float vw_x = vy * wz - vz * wy; + float vw_y = vz * wx - vx * wz; + float vw_z = vx * wy - vy * wx; + + float mag = (float)Math.Sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + if (mag < 0.000001f) + { + mag = 0; + } + else + { + mag = 1.0f / mag; + } + + float x = vw_x * mag; + float y = vw_y * mag; + float z = vw_z * mag; + + float D = 0.0f - ((x * A[0]) + (y * A[1]) + (z * A[2])); + + plane.x = x; + plane.y = y; + plane.z = z; + plane.w = D; + } + + public static void splitRect(int axis, Rect3d source, Rect3d b1, Rect3d b2, float[] midpoint) + { + switch (axis) + { + case 0: + b1.SetMin(source.mMin); + b1.SetMax(midpoint[0], source.mMax[1], source.mMax[2]); + + b2.SetMin(midpoint[0], source.mMin[1], source.mMin[2]); + b2.SetMax(source.mMax); + break; + case 1: + b1.SetMin(source.mMin); + b1.SetMax(source.mMax[0], midpoint[1], source.mMax[2]); + + b2.SetMin(source.mMin[0], midpoint[1], source.mMin[2]); + b2.SetMax(source.mMax); + break; + case 2: + b1.SetMin(source.mMin); + b1.SetMax(source.mMax[0], source.mMax[1], midpoint[2]); + + b2.SetMin(source.mMin[0], source.mMin[1], midpoint[2]); + b2.SetMax(source.mMax); + break; + } + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs new file mode 100644 index 0000000..6f17c9f --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs @@ -0,0 +1,70 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class VertexPool + { + private List mVertices = new List(); + private Dictionary mIndices = new Dictionary(); + + public int getIndex(float3 vtx) + { + int idx; + if (mIndices.TryGetValue(vtx, out idx)) + return idx; + + idx = mVertices.Count; + mVertices.Add(vtx); + mIndices.Add(vtx, idx); + return idx; + } + + public float3 Get(int idx) + { + return mVertices[idx]; + } + + public int GetSize() + { + return mVertices.Count; + } + + public List GetVertices() + { + return mVertices; + } + + public void Clear() + { + mVertices.Clear(); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs new file mode 100644 index 0000000..ce88fc8 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs @@ -0,0 +1,70 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class float2 + { + public float x; + public float y; + + public float2() + { + } + + public float2(float _x, float _y) + { + x = _x; + y = _y; + } + + public float this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + } + throw new ArgumentOutOfRangeException(); + } + } + + public static float2 operator -(float2 a, float2 b) + { + return new float2(a.x - b.x, a.y - b.y); + } + + public static float2 operator +(float2 a, float2 b) + { + return new float2(a.x + b.x, a.y + b.y); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs new file mode 100644 index 0000000..4389114 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs @@ -0,0 +1,444 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class float3 : IEquatable + { + public float x; + public float y; + public float z; + + public float3() + { + x = 0; + y = 0; + z = 0; + } + + public float3(float _x, float _y, float _z) + { + x = _x; + y = _y; + z = _z; + } + + public float3(float3 f) + { + x = f.x; + y = f.y; + z = f.z; + } + + public float this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + case 2: return z; + } + throw new ArgumentOutOfRangeException(); + } + } + + public float Distance(float3 a) + { + float3 d = new float3(a.x - x, a.y - y, a.z - z); + return d.Length(); + } + + public float Distance2(float3 a) + { + float dx = a.x - x; + float dy = a.y - y; + float dz = a.z - z; + return dx * dx + dy * dy + dz * dz; + } + + public float Length() + { + return (float)Math.Sqrt(x * x + y * y + z * z); + } + + public float Area(float3 p1, float3 p2) + { + float A = Partial(p1); + A += p1.Partial(p2); + A += p2.Partial(this); + return A * 0.5f; + } + + public float Partial(float3 p) + { + return (x * p.y) - (p.x * y); + } + + // Given a point and a line (defined by two points), compute the closest point + // in the line. (The line is treated as infinitely long.) + public void NearestPointInLine(float3 point, float3 line0, float3 line1) + { + float3 nearestPoint = new float3(); + float3 lineDelta = line1 - line0; + + // Handle degenerate lines + if (lineDelta == float3.Zero) + { + nearestPoint = line0; + } + else + { + float delta = float3.dot(point - line0, lineDelta) / float3.dot(lineDelta, lineDelta); + nearestPoint = line0 + lineDelta * delta; + } + + this.x = nearestPoint.x; + this.y = nearestPoint.y; + this.z = nearestPoint.z; + } + + // Given a point and a line segment (defined by two points), compute the closest point + // in the line. Cap the point at the endpoints of the line segment. + public void NearestPointInLineSegment(float3 point, float3 line0, float3 line1) + { + float3 nearestPoint = new float3(); + float3 lineDelta = line1 - line0; + + // Handle degenerate lines + if (lineDelta == Zero) + { + nearestPoint = line0; + } + else + { + float delta = float3.dot(point - line0, lineDelta) / float3.dot(lineDelta, lineDelta); + + // Clamp the point to conform to the segment's endpoints + if (delta < 0) + delta = 0; + else if (delta > 1) + delta = 1; + + nearestPoint = line0 + lineDelta * delta; + } + + this.x = nearestPoint.x; + this.y = nearestPoint.y; + this.z = nearestPoint.z; + } + + // Given a point and a triangle (defined by three points), compute the closest point + // in the triangle. Clamp the point so it's confined to the area of the triangle. + public void NearestPointInTriangle(float3 point, float3 triangle0, float3 triangle1, float3 triangle2) + { + float3 nearestPoint = new float3(); + + float3 lineDelta0 = triangle1 - triangle0; + float3 lineDelta1 = triangle2 - triangle0; + + // Handle degenerate triangles + if ((lineDelta0 == Zero) || (lineDelta1 == Zero)) + { + nearestPoint.NearestPointInLineSegment(point, triangle1, triangle2); + } + else if (lineDelta0 == lineDelta1) + { + nearestPoint.NearestPointInLineSegment(point, triangle0, triangle1); + } + else + { + float3[] axis = new float3[3] { new float3(), new float3(), new float3() }; + axis[0].NearestPointInLine(triangle0, triangle1, triangle2); + axis[1].NearestPointInLine(triangle1, triangle0, triangle2); + axis[2].NearestPointInLine(triangle2, triangle0, triangle1); + + float3 axisDot = new float3(); + axisDot.x = dot(triangle0 - axis[0], point - axis[0]); + axisDot.y = dot(triangle1 - axis[1], point - axis[1]); + axisDot.z = dot(triangle2 - axis[2], point - axis[2]); + + bool bForce = true; + float bestMagnitude2 = 0; + float closeMagnitude2; + float3 closePoint = new float3(); + + if (axisDot.x < 0f) + { + closePoint.NearestPointInLineSegment(point, triangle1, triangle2); + closeMagnitude2 = point.Distance2(closePoint); + if (bForce || (bestMagnitude2 > closeMagnitude2)) + { + bForce = false; + bestMagnitude2 = closeMagnitude2; + nearestPoint = closePoint; + } + } + if (axisDot.y < 0f) + { + closePoint.NearestPointInLineSegment(point, triangle0, triangle2); + closeMagnitude2 = point.Distance2(closePoint); + if (bForce || (bestMagnitude2 > closeMagnitude2)) + { + bForce = false; + bestMagnitude2 = closeMagnitude2; + nearestPoint = closePoint; + } + } + if (axisDot.z < 0f) + { + closePoint.NearestPointInLineSegment(point, triangle0, triangle1); + closeMagnitude2 = point.Distance2(closePoint); + if (bForce || (bestMagnitude2 > closeMagnitude2)) + { + bForce = false; + bestMagnitude2 = closeMagnitude2; + nearestPoint = closePoint; + } + } + + // If bForce is true at this point, it means the nearest point lies + // inside the triangle; use the nearest-point-on-a-plane equation + if (bForce) + { + float3 normal; + + // Get the normal of the polygon (doesn't have to be a unit vector) + normal = float3.cross(lineDelta0, lineDelta1); + + float3 pointDelta = point - triangle0; + float delta = float3.dot(normal, pointDelta) / float3.dot(normal, normal); + + nearestPoint = point - normal * delta; + } + } + + this.x = nearestPoint.x; + this.y = nearestPoint.y; + this.z = nearestPoint.z; + } + + public static float3 operator +(float3 a, float3 b) + { + return new float3(a.x + b.x, a.y + b.y, a.z + b.z); + } + + public static float3 operator -(float3 a, float3 b) + { + return new float3(a.x - b.x, a.y - b.y, a.z - b.z); + } + + public static float3 operator -(float3 a, float s) + { + return new float3(a.x - s, a.y - s, a.z - s); + } + + public static float3 operator -(float3 v) + { + return new float3(-v.x, -v.y, -v.z); + } + + public static float3 operator *(float3 v, float s) + { + return new float3(v.x * s, v.y * s, v.z * s); + } + + public static float3 operator *(float s, float3 v) + { + return new float3(v.x * s, v.y * s, v.z * s); + } + + public static float3 operator *(float3 v, float3x3 m) + { + return new float3((m.x.x * v.x + m.y.x * v.y + m.z.x * v.z), (m.x.y * v.x + m.y.y * v.y + m.z.y * v.z), (m.x.z * v.x + m.y.z * v.y + m.z.z * v.z)); + } + + public static float3 operator *(float3x3 m, float3 v) + { + return new float3(dot(m.x, v), dot(m.y, v), dot(m.z, v)); + } + + public static float3 operator /(float3 v, float s) + { + float sinv = 1.0f / s; + return new float3(v.x * sinv, v.y * sinv, v.z * sinv); + } + + public bool Equals(float3 other) + { + return this == other; + } + + public override bool Equals(object obj) + { + float3 f = obj as float3; + if (f == null) + return false; + + return this == f; + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode(); + } + + public static bool operator ==(float3 a, float3 b) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(a, b)) + return true; + // If one is null, but not both, return false. + if (((object)a == null) || ((object)b == null)) + return false; + + return (a.x == b.x && a.y == b.y && a.z == b.z); + } + + public static bool operator !=(float3 a, float3 b) + { + return (a.x != b.x || a.y != b.y || a.z != b.z); + } + + public static float dot(float3 a, float3 b) + { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + + public static float3 cmul(float3 v1, float3 v2) + { + return new float3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); + } + + public static float3 cross(float3 a, float3 b) + { + return new float3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); + } + + public static float3 Interpolate(float3 v0, float3 v1, float alpha) + { + return v0 * (1 - alpha) + v1 * alpha; + } + + public static float3 Round(float3 a, int digits) + { + return new float3((float)Math.Round(a.x, digits), (float)Math.Round(a.y, digits), (float)Math.Round(a.z, digits)); + } + + public static float3 VectorMax(float3 a, float3 b) + { + return new float3(Math.Max(a.x, b.x), Math.Max(a.y, b.y), Math.Max(a.z, b.z)); + } + + public static float3 VectorMin(float3 a, float3 b) + { + return new float3(Math.Min(a.x, b.x), Math.Min(a.y, b.y), Math.Min(a.z, b.z)); + } + + public static float3 vabs(float3 v) + { + return new float3(Math.Abs(v.x), Math.Abs(v.y), Math.Abs(v.z)); + } + + public static float magnitude(float3 v) + { + return (float)Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z); + } + + public static float3 normalize(float3 v) + { + float d = magnitude(v); + if (d == 0) + d = 0.1f; + d = 1 / d; + return new float3(v.x * d, v.y * d, v.z * d); + } + + public static float3 safenormalize(float3 v) + { + if (magnitude(v) <= 0.0f) + return new float3(1, 0, 0); + else + return normalize(v); + } + + public static float Yaw(float3 v) + { + return (v.y == 0.0 && v.x == 0.0) ? 0.0f : (float)Math.Atan2(-v.x, v.y) * (180.0f / 3.14159264f); + } + + public static float Pitch(float3 v) + { + return (float)Math.Atan2(v.z, Math.Sqrt(v.x * v.x + v.y * v.y)) * (180.0f / 3.14159264f); + } + + public float ComputePlane(float3 A, float3 B, float3 C) + { + float vx, vy, vz, wx, wy, wz, vw_x, vw_y, vw_z, mag; + + vx = (B.x - C.x); + vy = (B.y - C.y); + vz = (B.z - C.z); + + wx = (A.x - B.x); + wy = (A.y - B.y); + wz = (A.z - B.z); + + vw_x = vy * wz - vz * wy; + vw_y = vz * wx - vx * wz; + vw_z = vx * wy - vy * wx; + + mag = (float)Math.Sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + if (mag < 0.000001f) + { + mag = 0; + } + else + { + mag = 1.0f / mag; + } + + x = vw_x * mag; + y = vw_y * mag; + z = vw_z * mag; + + float D = 0.0f - ((x * A.x) + (y * A.y) + (z * A.z)); + return D; + } + + public override string ToString() + { + return String.Format("<{0}, {1}, {2}>", x, y, z); + } + + public static readonly float3 Zero = new float3(); + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs new file mode 100644 index 0000000..76cf063 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs @@ -0,0 +1,195 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class float3x3 + { + public float3 x = new float3(); + public float3 y = new float3(); + public float3 z = new float3(); + + public float3x3() + { + } + + public float3x3(float xx, float xy, float xz, float yx, float yy, float yz, float zx, float zy, float zz) + { + x = new float3(xx, xy, xz); + y = new float3(yx, yy, yz); + z = new float3(zx, zy, zz); + } + + public float3x3(float3 _x, float3 _y, float3 _z) + { + x = new float3(_x); + y = new float3(_y); + z = new float3(_z); + } + + public float3 this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + case 2: return z; + } + throw new ArgumentOutOfRangeException(); + } + } + + public float this[int i, int j] + { + get + { + switch (i) + { + case 0: + switch (j) + { + case 0: return x.x; + case 1: return x.y; + case 2: return x.z; + } + break; + case 1: + switch (j) + { + case 0: return y.x; + case 1: return y.y; + case 2: return y.z; + } + break; + case 2: + switch (j) + { + case 0: return z.x; + case 1: return z.y; + case 2: return z.z; + } + break; + } + throw new ArgumentOutOfRangeException(); + } + set + { + switch (i) + { + case 0: + switch (j) + { + case 0: x.x = value; return; + case 1: x.y = value; return; + case 2: x.z = value; return; + } + break; + case 1: + switch (j) + { + case 0: y.x = value; return; + case 1: y.y = value; return; + case 2: y.z = value; return; + } + break; + case 2: + switch (j) + { + case 0: z.x = value; return; + case 1: z.y = value; return; + case 2: z.z = value; return; + } + break; + } + throw new ArgumentOutOfRangeException(); + } + } + + public static float3x3 Transpose(float3x3 m) + { + return new float3x3(new float3(m.x.x, m.y.x, m.z.x), new float3(m.x.y, m.y.y, m.z.y), new float3(m.x.z, m.y.z, m.z.z)); + } + + public static float3x3 operator *(float3x3 a, float3x3 b) + { + return new float3x3(a.x * b, a.y * b, a.z * b); + } + + public static float3x3 operator *(float3x3 a, float s) + { + return new float3x3(a.x * s, a.y * s, a.z * s); + } + + public static float3x3 operator /(float3x3 a, float s) + { + float t = 1f / s; + return new float3x3(a.x * t, a.y * t, a.z * t); + } + + public static float3x3 operator +(float3x3 a, float3x3 b) + { + return new float3x3(a.x + b.x, a.y + b.y, a.z + b.z); + } + + public static float3x3 operator -(float3x3 a, float3x3 b) + { + return new float3x3(a.x - b.x, a.y - b.y, a.z - b.z); + } + + public static float Determinant(float3x3 m) + { + return m.x.x * m.y.y * m.z.z + m.y.x * m.z.y * m.x.z + m.z.x * m.x.y * m.y.z - m.x.x * m.z.y * m.y.z - m.y.x * m.x.y * m.z.z - m.z.x * m.y.y * m.x.z; + } + + public static float3x3 Inverse(float3x3 a) + { + float3x3 b = new float3x3(); + float d = Determinant(a); + Debug.Assert(d != 0); + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + int j1 = (j + 1) % 3; + int j2 = (j + 2) % 3; + + // reverse indexs i&j to take transpose + b[i, j] = (a[i1][j1] * a[i2][j2] - a[i1][j2] * a[i2][j1]) / d; + } + } + return b; + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs new file mode 100644 index 0000000..fa60876 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs @@ -0,0 +1,170 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class float4 + { + public float x; + public float y; + public float z; + public float w; + + public float4() + { + x = 0; + y = 0; + z = 0; + w = 0; + } + + public float4(float _x, float _y, float _z, float _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + + public float4(float3 v, float _w) + { + x = v.x; + y = v.y; + z = v.z; + w = _w; + } + + public float4(float4 f) + { + x = f.x; + y = f.y; + z = f.z; + w = f.w; + } + + public float this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + } + throw new ArgumentOutOfRangeException(); + } + } + + public float3 xyz() + { + return new float3(x, y, z); + } + + public void setxyz(float3 xyz) + { + x = xyz.x; + y = xyz.y; + z = xyz.z; + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + } + + public override bool Equals(object obj) + { + float4 f = obj as float4; + if (f == null) + return false; + + return this == f; + } + + public static float4 Homogenize(float3 v3) + { + return Homogenize(v3, 1.0f); + } + + //C++ TO C# CONVERTER NOTE: C# does not allow default values for parameters. Overloaded methods are inserted above. + //ORIGINAL LINE: float4 Homogenize(const float3 &v3, const float &w =1.0f) + public static float4 Homogenize(float3 v3, float w) + { + return new float4(v3.x, v3.y, v3.z, w); + } + + public static float4 cmul(float4 a, float4 b) + { + return new float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); + } + + public static float4 operator +(float4 a, float4 b) + { + return new float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); + } + public static float4 operator -(float4 a, float4 b) + { + return new float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); + } + + public static float4 operator *(float4 v, float4x4 m) + { + return v.x * m.x + v.y * m.y + v.z * m.z + v.w * m.w; // yes this actually works + } + + public static bool operator ==(float4 a, float4 b) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(a, b)) + return true; + // If one is null, but not both, return false. + if (((object)a == null) || ((object)b == null)) + return false; + + return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); + } + + public static bool operator !=(float4 a, float4 b) + { + return !(a == b); + } + + public static float4 operator *(float4 v, float s) + { + return new float4(v.x * s, v.y * s, v.z * s, v.w * s); + } + + public static float4 operator *(float s, float4 v) + { + return new float4(v.x * s, v.y * s, v.z * s, v.w * s); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs new file mode 100644 index 0000000..7d1592f --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs @@ -0,0 +1,284 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class float4x4 + { + public float4 x = new float4(); + public float4 y = new float4(); + public float4 z = new float4(); + public float4 w = new float4(); + + public float4x4() + { + } + + public float4x4(float4 _x, float4 _y, float4 _z, float4 _w) + { + x = new float4(_x); + y = new float4(_y); + z = new float4(_z); + w = new float4(_w); + } + + public float4x4( + float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) + { + x = new float4(m00, m01, m02, m03); + y = new float4(m10, m11, m12, m13); + z = new float4(m20, m21, m22, m23); + w = new float4(m30, m31, m32, m33); + } + + public float4x4(float4x4 m) + { + x = new float4(m.x); + y = new float4(m.y); + z = new float4(m.z); + w = new float4(m.w); + } + + public float4 this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + } + throw new ArgumentOutOfRangeException(); + } + set + { + switch (i) + { + case 0: x = value; return; + case 1: y = value; return; + case 2: z = value; return; + case 3: w = value; return; + } + throw new ArgumentOutOfRangeException(); + } + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + } + + public override bool Equals(object obj) + { + float4x4 m = obj as float4x4; + if (m == null) + return false; + + return this == m; + } + + public static float4x4 operator *(float4x4 a, float4x4 b) + { + return new float4x4(a.x * b, a.y * b, a.z * b, a.w * b); + } + + public static bool operator ==(float4x4 a, float4x4 b) + { + return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); + } + + public static bool operator !=(float4x4 a, float4x4 b) + { + return !(a == b); + } + + public static float4x4 Inverse(float4x4 m) + { + float4x4 d = new float4x4(); + //float dst = d.x.x; + float[] tmp = new float[12]; // temp array for pairs + float[] src = new float[16]; // array of transpose source matrix + float det; // determinant + // transpose matrix + for (int i = 0; i < 4; i++) + { + src[i] = m[i].x; + src[i + 4] = m[i].y; + src[i + 8] = m[i].z; + src[i + 12] = m[i].w; + } + // calculate pairs for first 8 elements (cofactors) + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + // calculate first 8 elements (cofactors) + d.x.x = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; + d.x.x -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; + d.x.y = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; + d.x.y -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; + d.x.z = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; + d.x.z -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; + d.x.w = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; + d.x.w -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; + d.y.x = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; + d.y.x -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; + d.y.y = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; + d.y.y -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; + d.y.z = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; + d.y.z -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; + d.y.w = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; + d.y.w -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; + // calculate pairs for second 8 elements (cofactors) + tmp[0] = src[2]*src[7]; + tmp[1] = src[3]*src[6]; + tmp[2] = src[1]*src[7]; + tmp[3] = src[3]*src[5]; + tmp[4] = src[1]*src[6]; + tmp[5] = src[2]*src[5]; + tmp[6] = src[0]*src[7]; + tmp[7] = src[3]*src[4]; + tmp[8] = src[0]*src[6]; + tmp[9] = src[2]*src[4]; + tmp[10] = src[0]*src[5]; + tmp[11] = src[1]*src[4]; + // calculate second 8 elements (cofactors) + d.z.x = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; + d.z.x -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; + d.z.y = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; + d.z.y -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; + d.z.z = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; + d.z.z -= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; + d.z.w = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; + d.z.w-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; + d.w.x = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; + d.w.x-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; + d.w.y = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; + d.w.y-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; + d.w.z = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; + d.w.z-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; + d.w.w = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; + d.w.w-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; + // calculate determinant + det = src[0] * d.x.x + src[1] * d.x.y + src[2] * d.x.z + src[3] * d.x.w; + // calculate matrix inverse + det = 1/det; + for (int j = 0; j < 4; j++) + d[j] *= det; + return d; + } + + public static float4x4 MatrixRigidInverse(float4x4 m) + { + float4x4 trans_inverse = MatrixTranslation(-m.w.xyz()); + float4x4 rot = new float4x4(m); + rot.w = new float4(0f, 0f, 0f, 1f); + return trans_inverse * MatrixTranspose(rot); + } + public static float4x4 MatrixTranspose(float4x4 m) + { + return new float4x4(m.x.x, m.y.x, m.z.x, m.w.x, m.x.y, m.y.y, m.z.y, m.w.y, m.x.z, m.y.z, m.z.z, m.w.z, m.x.w, m.y.w, m.z.w, m.w.w); + } + public static float4x4 MatrixPerspectiveFov(float fovy, float aspect, float zn, float zf) + { + float h = 1.0f / (float)Math.Tan(fovy / 2.0f); // view space height + float w = h / aspect; // view space width + return new float4x4(w, 0, 0, 0, 0, h, 0, 0, 0, 0, zf / (zn - zf), -1, 0, 0, zn * zf / (zn - zf), 0); + } + public static float4x4 MatrixTranslation(float3 t) + { + return new float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, t.z, 1); + } + public static float4x4 MatrixRotationZ(float angle_radians) + { + float s = (float)Math.Sin(angle_radians); + float c = (float)Math.Cos(angle_radians); + return new float4x4(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + public static float4x4 MatrixLookAt(float3 eye, float3 at, float3 up) + { + float4x4 m = new float4x4(); + m.w.w = 1.0f; + m.w.setxyz(eye); + m.z.setxyz(float3.normalize(eye - at)); + m.x.setxyz(float3.normalize(float3.cross(up, m.z.xyz()))); + m.y.setxyz(float3.cross(m.z.xyz(), m.x.xyz())); + return MatrixRigidInverse(m); + } + + public static float4x4 MatrixFromQuatVec(Quaternion q, float3 v) + { + // builds a 4x4 transformation matrix based on orientation q and translation v + float qx2 = q.x * q.x; + float qy2 = q.y * q.y; + float qz2 = q.z * q.z; + + float qxqy = q.x * q.y; + float qxqz = q.x * q.z; + float qxqw = q.x * q.w; + float qyqz = q.y * q.z; + float qyqw = q.y * q.w; + float qzqw = q.z * q.w; + + return new float4x4( + 1 - 2 * (qy2 + qz2), + 2 * (qxqy + qzqw), + 2 * (qxqz - qyqw), + 0, + 2 * (qxqy - qzqw), + 1 - 2 * (qx2 + qz2), + 2 * (qyqz + qxqw), + 0, + 2 * (qxqz + qyqw), + 2 * (qyqz - qxqw), + 1 - 2 * (qx2 + qy2), + 0, + v.x, + v.y, + v.z, + 1.0f); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs new file mode 100644 index 0000000..9c5760d --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs @@ -0,0 +1,128 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class int3 + { + public int x; + public int y; + public int z; + + public int3() + { + } + + public int3(int _x, int _y, int _z) + { + x = _x; + y = _y; + z = _z; + } + + public int this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + case 2: return z; + } + throw new ArgumentOutOfRangeException(); + } + set + { + switch (i) + { + case 0: x = value; return; + case 1: y = value; return; + case 2: z = value; return; + } + throw new ArgumentOutOfRangeException(); + } + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode(); + } + + public override bool Equals(object obj) + { + int3 i = obj as int3; + if (i == null) + return false; + + return this == i; + } + + public static bool operator ==(int3 a, int3 b) + { + // If both are null, or both are same instance, return true. + if (System.Object.ReferenceEquals(a, b)) + return true; + // If one is null, but not both, return false. + if (((object)a == null) || ((object)b == null)) + return false; + + for (int i = 0; i < 3; i++) + { + if (a[i] != b[i]) + return false; + } + return true; + } + + public static bool operator !=(int3 a, int3 b) + { + return !(a == b); + } + + public static int3 roll3(int3 a) + { + int tmp = a[0]; + a[0] = a[1]; + a[1] = a[2]; + a[2] = tmp; + return a; + } + + public static bool isa(int3 a, int3 b) + { + return (a == b || roll3(a) == b || a == roll3(b)); + } + + public static bool b2b(int3 a, int3 b) + { + return isa(a, new int3(b[2], b[1], b[0])); + } + } +} diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs new file mode 100644 index 0000000..c2b32e5 --- /dev/null +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs @@ -0,0 +1,66 @@ +/* The MIT License + * + * Copyright (c) 2010 Intel Corporation. + * All rights reserved. + * + * Based on the convexdecomposition library from + * by John W. Ratcliff and Stan Melax. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OpenSim.Region.Physics.ConvexDecompositionDotNet +{ + public class int4 + { + public int x; + public int y; + public int z; + public int w; + + public int4() + { + } + + public int4(int _x, int _y, int _z, int _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + + public int this[int i] + { + get + { + switch (i) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + } + throw new ArgumentOutOfRangeException(); + } + } + } +} -- cgit v1.1 From 04f8d0e45dae6b773e49532e4cd31ee290f9a677 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Thu, 7 Jul 2011 23:36:41 +0900 Subject: Made some LSL_Constant or LS_Constant raw int values --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 461b473..0839ab4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -1741,8 +1741,13 @@ namespace OpenSim.Region.ScriptEngine.Shared public override bool Equals(Object o) { - if (!(o is LSLInteger)) - return false; + if (!(o is LSLInteger)) { + if(o is int) { + return value == (int)o; + } else { + return false; + } + } return value == ((LSLInteger)o).value; } -- cgit v1.1 From b983f38e2abc4ee28a572c680ba267138064ed5c Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Thu, 7 Jul 2011 23:38:22 +0900 Subject: lsGetWindlightScene() returns raw int value, which makes unable to compare to another value with llListFindList() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 645566e..80daf5b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -130,7 +130,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int idx = 0; while (idx < rules.Length) { - uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_Integer ruleInt = rules.GetLSLIntegerItem(idx); + uint rule = (uint)ruleInt; LSL_List toadd = new LSL_List(); switch (rule) @@ -247,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (toadd.Length > 0) { - values.Add(rule); + values.Add(ruleInt); values.Add(toadd.Data[0]); } idx++; -- cgit v1.1 From 52c3671aa07c5d4c91908a8e1b15b76e96cc49c0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jul 2011 01:17:35 +0100 Subject: fix formatting issues from last patch --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 0839ab4..e0a4014 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -1741,13 +1741,18 @@ namespace OpenSim.Region.ScriptEngine.Shared public override bool Equals(Object o) { - if (!(o is LSLInteger)) { - if(o is int) { + if (!(o is LSLInteger)) + { + if (o is int) + { return value == (int)o; - } else { + } + else + { return false; } } + return value == ((LSLInteger)o).value; } -- cgit v1.1 From f680c134955b3179265ec197c935ed86b397b6ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jul 2011 01:24:30 +0100 Subject: Fix osMatchString() so that it reports all instance of pattern matches, not just the first one. This is a slight adaptation of the patch in http://opensimulator.org/mantis/view.php?id=4568 which doesn't apply directly since the underlying code was changed by earlier makopoppo patches. Thanks makopoppo! --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b3f90e2..b710229 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1909,8 +1909,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api }; return NotecardCache.GetLines(assetID); - - } public string osAvatarName2Key(string firstname, string lastname) @@ -2024,7 +2022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Find matches beginning at start position Regex matcher = new Regex(pattern); Match match = matcher.Match(src, start); - if (match.Success) + while (match.Success) { foreach (System.Text.RegularExpressions.Group g in match.Groups) { @@ -2034,6 +2032,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api result.Add(new LSL_Integer(g.Index)); } } + + match = match.NextMatch(); } return result; -- cgit v1.1 From df586c9d2502523395b53d48ddd7dda8832c7a08 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Tue, 5 Jul 2011 22:19:26 +0900 Subject: Raw int numbers (ex.LSL Constants) are displayed like "1.000000" when type cast to string --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index e0a4014..bf66b12 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -1396,6 +1396,12 @@ namespace OpenSim.Region.ScriptEngine.Shared string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value); m_string=s; } + + public LSLString(int i) + { + string s = String.Format("{0}", i); + m_string = s; + } public LSLString(LSLInteger i) { @@ -1469,6 +1475,11 @@ namespace OpenSim.Region.ScriptEngine.Shared { return new LSLString(d); } + + static public explicit operator LSLString(int i) + { + return new LSLString(i); + } public static explicit operator LSLString(LSLFloat f) { -- cgit v1.1 From 6963b8b046f8a236d5a6e75a0fed81103d807c21 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jul 2011 01:28:27 +0100 Subject: refactor: Get LSLString(LSLInteger i) constructor to now call LSLString(int i) structure to remove code duplication. --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index bf66b12..d848b2a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -1379,7 +1379,9 @@ namespace OpenSim.Region.ScriptEngine.Shared public struct LSLString { public string m_string; + #region Constructors + public LSLString(string s) { m_string = s; @@ -1387,14 +1389,14 @@ namespace OpenSim.Region.ScriptEngine.Shared public LSLString(double d) { - string s=String.Format(Culture.FormatProvider, "{0:0.000000}", d); - m_string=s; + string s = String.Format(Culture.FormatProvider, "{0:0.000000}", d); + m_string = s; } public LSLString(LSLFloat f) { string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value); - m_string=s; + m_string = s; } public LSLString(int i) @@ -1403,12 +1405,8 @@ namespace OpenSim.Region.ScriptEngine.Shared m_string = s; } - public LSLString(LSLInteger i) - { - string s = String.Format("{0}", i); - m_string = s; - } - + public LSLString(LSLInteger i) : this(i.value) {} + #endregion #region Operators -- cgit v1.1 From f99b89990c9e4b136b77125c680c7a7c510a6ef2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jul 2011 02:21:56 +0100 Subject: Add scratch AvatarFactoryModuleTests with one test to do a partial check on AvatarFactoryModule.SetAppearance() Baked texture set not yet checked, nor persistence of data in avatar service This is a foundation for later npc related tests. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 24 +++++--- .../Tests/AvatarFactoryModuleTests.cs | 72 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index d02a305..1955e5b 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -116,16 +116,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory #endregion /// - /// Check for the existence of the baked texture assets. Request a rebake - /// unless checkonly is true. + /// Check for the existence of the baked texture assets. /// /// - /// public bool ValidateBakedTextureCache(IClientAPI client) { return ValidateBakedTextureCache(client, true); } - + + /// + /// Check for the existence of the baked texture assets. Request a rebake + /// unless checkonly is true. + /// + /// + /// private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly) { ScenePresence sp = m_scene.GetScenePresence(client.AgentId); @@ -156,13 +160,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory defonly = false; // found a non-default texture reference - if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + if (!CheckBakedTextureAsset(client, face.TextureID, idx)) { // the asset didn't exist if we are only checking, then we found a bad // one and we're done otherwise, ask for a rebake - if (checkonly) return false; + if (checkonly) + return false; m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID); + client.SendRebakeAvatarTextures(face.TextureID); } } @@ -183,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId); return; } @@ -211,7 +217,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId); - Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); }); + Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); }); // This appears to be set only in the final stage of the appearance // update transaction. In theory, we should be able to do an immediate @@ -220,9 +226,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // save only if there were changes, send no matter what (doesn't hurt to send twice) if (changed) QueueAppearanceSave(client.AgentId); + QueueAppearanceSend(client.AgentId); } - } // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs new file mode 100644 index 0000000..cf4c331 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -0,0 +1,72 @@ +/* + * 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 NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory +{ + [TestFixture] + public class AvatarFactoryModuleTests + { + /// + /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service. + /// + [Test] + public void TestSetAppearance() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID userId = TestHelper.ParseTail(0x1); + + AvatarFactoryModule afm = new AvatarFactoryModule(); + TestScene scene = SceneSetupHelpers.SetupScene(); + SceneSetupHelpers.SetupSceneModules(scene, afm); + + AgentCircuitData acd = new AgentCircuitData(); + acd.AgentID = userId; + TestClient tc = SceneSetupHelpers.AddRootAgent(scene, acd); + + byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; + for (byte i = 0; i < visualParams.Length; i++) + visualParams[i] = i; + + afm.SetAppearance(tc, new Primitive.TextureEntry(TestHelper.ParseTail(0x10)), visualParams); + + ScenePresence sp = scene.GetScenePresence(userId); + + // TODO: Check baked texture + Assert.AreEqual(visualParams, sp.Appearance.VisualParams); + } + } +} \ No newline at end of file -- cgit v1.1 From 59aedbc94b345a964fc404c22247afd0487b6f54 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jul 2011 02:25:40 +0100 Subject: Rename SceneSetupHelpers.AddRootAgent to AddClient() to better represent its effects and return object --- .../Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs | 4 ++-- OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index cf4c331..736dd72 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory AgentCircuitData acd = new AgentCircuitData(); acd.AgentID = userId; - TestClient tc = SceneSetupHelpers.AddRootAgent(scene, acd); + TestClient tc = SceneSetupHelpers.AddClient(scene, acd); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs index cff649b..5586c65 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests region1 = scene.RegionInfo.RegionHandle; region2 = scene2.RegionInfo.RegionHandle; - SceneSetupHelpers.AddRootAgent(scene, agent1); + SceneSetupHelpers.AddClient(scene, agent1); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 0a82c4f..260d1c0 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -139,7 +139,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); - IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); + IClientAPI client = SceneSetupHelpers.AddClient(scene, agentId); scene.DeRezObjects(client, new System.Collections.Generic.List() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index 5357a06..1b8c100 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); - TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); + TestClient client = SceneSetupHelpers.AddClient(scene, userId); // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; @@ -105,7 +105,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); - TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); + TestClient client = SceneSetupHelpers.AddClient(scene, userId); // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index 77bd4c2..8425d37 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests new GroupsModule(), new MockGroupsServicesConnector() }); - TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); + TestClient client = SceneSetupHelpers.AddClient(scene, userId); IGroupsModule groupsModule = scene.RequestModuleInterface(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs index 03ac252..a37b338 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs @@ -212,7 +212,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneSetupHelpers.SetupSceneModules(myScene1, configSource, etm); - SceneSetupHelpers.AddRootAgent(myScene1, agent1Id); + SceneSetupHelpers.AddClient(myScene1, agent1Id); ScenePresence childPresence = myScene2.GetScenePresence(agent1); // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents diff --git a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs index 1b5a54e..4074f5d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs @@ -125,7 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests sceneA.RegisterRegionWithGrid(); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); - TestClient client = SceneSetupHelpers.AddRootAgent(sceneA, agentId); + TestClient client = SceneSetupHelpers.AddClient(sceneA, agentId); ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface(); -- cgit v1.1 From 457ba9d1a29daa203e326c6b9711c9e1ad99475d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jul 2011 02:27:47 +0100 Subject: refactor: slightly simplify test --- .../Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 736dd72..07de908 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -52,10 +52,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneSetupHelpers.SetupScene(); SceneSetupHelpers.SetupSceneModules(scene, afm); - - AgentCircuitData acd = new AgentCircuitData(); - acd.AgentID = userId; - TestClient tc = SceneSetupHelpers.AddClient(scene, acd); + TestClient tc = SceneSetupHelpers.AddClient(scene, userId); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) -- cgit v1.1 From c964114f7e1fd76970db4904a9bfd6a2cfad10b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 02:09:11 +0100 Subject: refactor: make argument to SOP.UpdatePrimFlags() more readable --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 33 +++++++++++++--------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 307c92a..1a58952 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1068,7 +1068,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public bool CreateSelected { get { return m_createSelected; } @@ -1241,7 +1240,9 @@ namespace OpenSim.Region.Framework.Scenes /// /// Property flags. See OpenMetaverse.PrimFlags /// + /// /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge + /// public PrimFlags Flags { get { return _flags; } @@ -4324,14 +4325,21 @@ namespace OpenSim.Region.Framework.Scenes } } - public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD) + /// + /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. + /// + /// + /// + /// + /// + public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) { bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); bool wasVD = VolumeDetectActive; - if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD)) + if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD== wasVD)) { return; } @@ -4341,32 +4349,31 @@ namespace OpenSim.Region.Framework.Scenes // that... // ... if VD is changed, all others are not. // ... if one of the others is changed, VD is not. - if (IsVD) // VD is active, special logic applies + if (SetVD) // VD is active, special logic applies { // State machine logic for VolumeDetect // More logic below - bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom; + bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom; if (phanReset) // Phantom changes from on to off switch VD off too { - IsVD = false; // Switch it of for the course of this routine + SetVD = false; // Switch it of for the course of this routine VolumeDetectActive = false; // and also permanently if (PhysActor != null) PhysActor.SetVolumeDetect(0); // Let physics know about it too } else { - IsPhantom = false; // If volumedetect is active we don't want phantom to be applied. // If this is a new call to VD out of the state "phantom" // this will also cause the prim to be visible to physics + SetPhantom = false; } - } if (UsePhysics && IsJoint()) { - IsPhantom = true; + SetPhantom = true; } if (UsePhysics) @@ -4396,8 +4403,7 @@ namespace OpenSim.Region.Framework.Scenes } } - - if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints + if (SetPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); if (PhysActor != null) @@ -4471,7 +4477,7 @@ namespace OpenSim.Region.Framework.Scenes } } - if (IsVD) + if (SetVD) { // If the above logic worked (this is urgent candidate to unit tests!) // we now have a physicsactor. @@ -4496,8 +4502,7 @@ namespace OpenSim.Region.Framework.Scenes this.VolumeDetectActive = false; } - - if (IsTemporary) + if (SetTemporary) { AddFlag(PrimFlags.TemporaryOnRez); } -- cgit v1.1 From c6d4304a0442c606a1f87e440183ed0b7dbc384e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 02:11:16 +0100 Subject: refactor: very minor space insertion --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 1a58952..4fa3a68 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4339,7 +4339,7 @@ namespace OpenSim.Region.Framework.Scenes bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); bool wasVD = VolumeDetectActive; - if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD== wasVD)) + if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) { return; } -- cgit v1.1 From e68ae44b6b28565f6867051e5e0ec5d8ecea72cb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 02:11:37 +0100 Subject: minor: remove mono compiler warning --- OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs index 06cd14b..9cb5674 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes /// public class AsyncInventorySender { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; -- cgit v1.1 From 01b98c2e6267cb13cf18f8baeb2b38fd5b6a6cdf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 02:18:19 +0100 Subject: refactor: Make arguments for SceneObjectGroup.UpdatePrimFlags() more readable --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 42ac9aa..4b8e370 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2513,14 +2513,15 @@ namespace OpenSim.Region.Framework.Scenes /// Update prim flags for this group. /// /// - /// - /// - /// - public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect) + /// + /// + /// + /// + public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) { SceneObjectPart selectionPart = GetChildPart(localID); - if (IsTemporary) + if (SetTemporary) { DetachFromBackup(); // Remove from database and parcel prim count @@ -2545,7 +2546,7 @@ namespace OpenSim.Region.Framework.Scenes } for (int i = 0; i < parts.Length; i++) - parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); + parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect); } } @@ -3292,6 +3293,7 @@ namespace OpenSim.Region.Framework.Scenes { if (IsDeleted) return; + if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) return; -- cgit v1.1 From 6a15464b0ac731b678b224cb64c742957f36888f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 02:29:19 +0100 Subject: refactor: Make arguments to SceneGraph.UpdatePrimFlags() more readable --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a078291..7ec7ea3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1401,21 +1401,26 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Update the flags on a scene object. This covers properties such as phantom, physics and temporary. /// + /// + /// This is currently handling the incoming call from the client stack (e.g. LLClientView). + /// /// - /// + /// + /// + /// /// - /// This routine seems to get called when a user changes object settings in the viewer. - /// If some one can confirm that, please change the comment according. - protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient) + protected internal void UpdatePrimFlags( + uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { - group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom, false); // VolumeDetect can't be set via UI and will always be off when a change is made there + // VolumeDetect can't be set via UI and will always be off when a change is made there + group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false); } } } -- cgit v1.1 From ce85675e705888f95fe00b6516da20118cbb24e0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 02:29:51 +0100 Subject: comment out accidential ProcessTaints physics debug line left in code --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index b63168a..0cf2f5d 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -859,7 +859,7 @@ namespace OpenSim.Region.Physics.OdePlugin public void ProcessTaints(float timestep) { -Console.WriteLine("ProcessTaints for " + Name); +//Console.WriteLine("ProcessTaints for " + Name); if (m_taintadd) { changeadd(timestep); -- cgit v1.1 From 2f3d0e209ff5c3028e3e29179b67504be9b2f887 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 03:13:59 +0100 Subject: When a sculpt/mesh texture is received by a part on a callback request, don't do the unnecessary work of copying the base shape. Just setting the new base shape is enough to reinsert the sculpt data and set the taint. Also cleans up a few more left-in debugging messages. --- OpenSim/Region/Framework/Scenes/Scene.cs | 1 + .../Region/Framework/Scenes/SceneObjectGroup.cs | 3 +++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 28 +++++++++++++++------- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 3 ++- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 2 +- 5 files changed, 26 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ec6044b..8195a0d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1726,6 +1726,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Loads the World's objects /// + /// public virtual void LoadPrimsFromStorage(UUID regionID) { LoadingPrims = true; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 4b8e370..a184445 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3297,7 +3297,10 @@ namespace OpenSim.Region.Framework.Scenes if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) return; +// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4fa3a68..5b203e9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1810,7 +1810,6 @@ namespace OpenSim.Region.Framework.Scenes { ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); } - } else { @@ -1872,7 +1871,6 @@ namespace OpenSim.Region.Framework.Scenes PhysActor.IsPhysical = UsePhysics; - // If we're not what we're supposed to be in the physics scene, recreate ourselves. //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public @@ -1896,6 +1894,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } } @@ -2967,14 +2966,17 @@ namespace OpenSim.Region.Framework.Scenes //if (texture != null) { if (texture != null) + { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Setting sculpt data for {0} on SculptTextureCallback()", Name); + m_shape.SculptData = texture.Data; + } if (PhysActor != null) { - // Tricks physics engine into thinking we've changed the part shape. - PrimitiveBaseShape m_newshape = m_shape.Copy(); - PhysActor.Shape = m_newshape; - m_shape = m_newshape; + // Update the physics actor with the new loaded sculpt data and set the taint signal. + PhysActor.Shape = m_shape; m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } @@ -3270,11 +3272,14 @@ namespace OpenSim.Region.Framework.Scenes { m_parentGroup.SetAxisRotation(axis, rotate); } + //Cannot use ScriptBaseClass constants as no referance to it currently. if (axis == 2)//STATUS_ROTATE_X STATUS_ROTATE_X = rotate; + if (axis == 4)//STATUS_ROTATE_Y STATUS_ROTATE_Y = rotate; + if (axis == 8)//STATUS_ROTATE_Z STATUS_ROTATE_Z = rotate; } @@ -4418,6 +4423,7 @@ namespace OpenSim.Region.Framework.Scenes RemFlag(PrimFlags.Phantom); PhysicsActor pa = PhysActor; + if (pa == null) { // It's not phantom anymore. So make sure the physics engine get's knowledge of it @@ -4434,6 +4440,7 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { DoPhysicsPropertyUpdate(UsePhysics, true); + if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) @@ -4444,6 +4451,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + if ( ((AggregateScriptEvents & scriptEvents.collision) != 0) || ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || @@ -4454,8 +4462,8 @@ namespace OpenSim.Region.Framework.Scenes (CollisionSound != UUID.Zero) ) { - PhysActor.OnCollisionUpdate += PhysicsCollision; - PhysActor.SubscribeEvents(1000); + PhysActor.OnCollisionUpdate += PhysicsCollision; + PhysActor.SubscribeEvents(1000); } } } @@ -4492,13 +4500,15 @@ namespace OpenSim.Region.Framework.Scenes } } else - { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like + { + // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // (mumbles, well, at least if you have infinte CPU powers :-)) PhysicsActor pa = this.PhysActor; if (pa != null) { PhysActor.SetVolumeDetect(0); } + this.VolumeDetectActive = false; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 0cf2f5d..123c8ff 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2104,6 +2104,7 @@ Console.WriteLine("changeshape not need meshing"); parent.ChildSetGeom(this); } } + resetCollisionAccounting(); m_taintshape = false; } @@ -2343,7 +2344,7 @@ Console.WriteLine("changeshape not need meshing"); { lock (_parent_scene.OdeLock) { - m_isVolumeDetect = (param!=0); + m_isVolumeDetect = (param != 0); } } diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index f5172aa..99392cc 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -26,7 +26,7 @@ */ //#define USE_DRAWSTUFF -#define SPAM +//#define SPAM using System; using System.Collections.Generic; -- cgit v1.1 From 0badf3718d98f579e0942e7c888986820d1250a7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 03:35:29 +0100 Subject: refactor: push the part of SceneObjectGroup.CheckSculptAndLoad() that actually deals with the part into a SceneObjectPart.CheckSculptAndLoad() method --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 32 ++++++++++---------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 34 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a184445..fa23fcd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3288,7 +3288,14 @@ namespace OpenSim.Region.Framework.Scenes return retmass; } - + + /// + /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that + /// the physics engine can use it. + /// + /// + /// When the physics engine has finished with it, the sculpt data is discarded to save memory. + /// public void CheckSculptAndLoad() { if (IsDeleted) @@ -3302,24 +3309,15 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) - { - SceneObjectPart part = parts[i]; - if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) - { - // check if a previously decoded sculpt map has been cached - if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) - { - part.SculptTextureCallback(part.Shape.SculptTexture, null); - } - else - { - m_scene.AssetService.Get( - part.Shape.SculptTexture.ToString(), part, AssetReceived); - } - } - } + parts[i].CheckSculptAndLoad(); } + /// + /// Handle an asset received asynchronously from the asset service. + /// + /// + /// + /// protected void AssetReceived(string id, Object sender, AssetBase asset) { SceneObjectPart sop = (SceneObjectPart)sender; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5b203e9..ce7c53a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Reflection; using System.Runtime.Serialization; using System.Security.Permissions; @@ -4563,6 +4564,7 @@ namespace OpenSim.Region.Framework.Scenes m_shape.PathTaperY = shapeBlock.PathTaperY; m_shape.PathTwist = shapeBlock.PathTwist; m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; + if (PhysActor != null) { PhysActor.Shape = m_shape; @@ -4584,6 +4586,37 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics + /// engine can use it. + /// + /// + /// When the physics engine has finished with it, the sculpt data is discarded to save memory. + /// + public void CheckSculptAndLoad() + { +// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); + + if (ParentGroup.IsDeleted) + return; + + if ((ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) + return; + + if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero) + { + // check if a previously decoded sculpt map has been cached + if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString()))) + { + SculptTextureCallback(Shape.SculptTexture, null); + } + else + { + ParentGroup.Scene.AssetService.Get(Shape.SculptTexture.ToString(), this, AssetReceived); + } + } + } + + /// /// Update the textures on the part. /// /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() @@ -4819,6 +4852,7 @@ namespace OpenSim.Region.Framework.Scenes Inventory.ApplyNextOwnerPermissions(); } + public void UpdateLookAt() { try -- cgit v1.1 From 8e44a8e2b9a318143e8e5f8bb235356c6be5c5e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 03:47:49 +0100 Subject: Properly regenerate physics proxy when a mesh is resized. This is done in SOP.Resize(). More common code from callers needs to be refactored into this method to reduce confusing copy/pasting --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ce7c53a..2026c53 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2831,6 +2831,12 @@ namespace OpenSim.Region.Framework.Scenes StoreUndoState(); m_shape.Scale = scale; + // If we're a mesh/sculpt, then we need to tell the physics engine about our new size. To do this, we + // need to reinsert the sculpt data into the shape, since the physics engine deletes it when done to + // save memory + if (PhysActor != null) + CheckSculptAndLoad(); + ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); } @@ -4619,9 +4625,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// Update the textures on the part. /// + /// /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() /// not handling RGBA properly. Cycles through, and "fixes" the color /// info + /// /// public void UpdateTexture(Primitive.TextureEntry tex) { -- cgit v1.1 From 24efb021ffe668154fa990f0d5d6f06e31221cb7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 04:23:30 +0100 Subject: minor Tack the prim name on the end of the "experimental mesh proxy generation" message. Can probably comment out this message soon, once a few other issues are tidied up. --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index b79e1a1..5ca5f20 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -319,7 +319,7 @@ namespace OpenSim.Region.Physics.Meshing if (!useMeshiesPhysicsMesh) return null; - m_log.Debug("[MESH]: experimental mesh proxy generation"); + m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); OSD meshOsd = null; -- cgit v1.1 From dbd954d701027c417d8f468d19b735f46596cc8c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jul 2011 22:56:14 +0100 Subject: Fix permissions problem where newly uploaded meshes rezzed from inventory could not be copied by owner. --- OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs | 2 +- .../Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index d3bb0bc..b11210a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -687,7 +687,7 @@ namespace OpenSim.Region.ClientStack.Linden item.CurrentPermissions = (uint)PermissionMask.All; item.BasePermissions = (uint)PermissionMask.All; item.EveryOnePermissions = 0; - item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); + item.NextPermissions = (uint)PermissionMask.All; item.CreationDate = Util.UnixTimeSinceEpoch(); if (AddNewInventoryItem != null) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs index c9d7ae1..29a9199 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs @@ -124,7 +124,7 @@ namespace OpenSim.Region.ClientStack.Linden private Hashtable MeshUploadFlag(Hashtable mDhttpMethod) { - m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: MeshUploadFlag request"); +// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); OSDMap data = new OSDMap(); ScenePresence sp = m_scene.GetScenePresence(m_agentID); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index b7e79cc..b2f04f9 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -160,8 +160,6 @@ namespace OpenSim.Region.ClientStack.Linden } } // } - - string assetName = llsdRequest.name; string assetDes = llsdRequest.description; @@ -208,12 +206,10 @@ namespace OpenSim.Region.ClientStack.Linden return uploadResponse; } - public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, string assetType,UUID AgentID) { - sbyte assType = 0; sbyte inType = 0; @@ -266,10 +262,10 @@ namespace OpenSim.Region.ClientStack.Linden item.CurrentPermissions = (uint)PermissionMask.All; item.BasePermissions = (uint)PermissionMask.All; item.EveryOnePermissions = 0; - item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); + item.NextPermissions = (uint)PermissionMask.All; item.CreationDate = Util.UnixTimeSinceEpoch(); m_scene.AddInventoryItem(item); } } -} +} \ No newline at end of file -- cgit v1.1 From df0e5cc9fe9b0851ae5442bdeeb49ab7778d5fe1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jul 2011 02:33:09 +0100 Subject: When a mesh object is added to a scene, delay adding the physics actor until the sculpt data has been added to the shape (possibly via an async asset service request) This prevents spurious 'no asset data' for meshes added on startup. --- OpenSim/Region/Framework/Scenes/Scene.cs | 5 ++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 21 +++++++------- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 33 ++++++++++++---------- 5 files changed, 39 insertions(+), 29 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8195a0d..0104a96 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1751,8 +1751,9 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart rootPart = group.GetChildPart(group.UUID); rootPart.Flags &= ~PrimFlags.Scripted; rootPart.TrimPermissions(); - group.CheckSculptAndLoad(); - //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); + + // Don't do this here - it will get done later on when sculpt data is loaded. +// group.CheckSculptAndLoad(); } m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fa23fcd..905acd6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -584,7 +584,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentID = m_rootPart.LocalId; //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); } - + ApplyPhysics(m_scene.m_physicalPrim); // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2026c53..e9571aa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1896,7 +1896,12 @@ namespace OpenSim.Region.Framework.Scenes } } - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + // If this part is a sculpt then delay the physics update until we've asynchronously loaded the + // mesh data. + if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + CheckSculptAndLoad(); + else + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 123c8ff..56e3b7e 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -638,7 +638,7 @@ namespace OpenSim.Region.Physics.OdePlugin float profileEnd; if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) - { + { taperX1 = _pbs.PathScaleX * 0.01f; if (taperX1 > 1.0f) taperX1 = 2.0f - taperX1; @@ -648,9 +648,9 @@ namespace OpenSim.Region.Physics.OdePlugin if (taperY1 > 1.0f) taperY1 = 2.0f - taperY1; taperY = 1.0f - taperY1; - } + } else - { + { taperX = _pbs.PathTaperX * 0.01f; if (taperX < 0.0f) taperX = -taperX; @@ -660,9 +660,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (taperY < 0.0f) taperY = -taperY; taperY1 = 1.0f - taperY; - - } - + } volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); @@ -859,7 +857,9 @@ namespace OpenSim.Region.Physics.OdePlugin public void ProcessTaints(float timestep) { -//Console.WriteLine("ProcessTaints for " + Name); +#if SPAM +Console.WriteLine("ZProcessTaints for " + Name); +#endif if (m_taintadd) { changeadd(timestep); @@ -1323,7 +1323,9 @@ namespace OpenSim.Region.Physics.OdePlugin public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) { -//Console.WriteLine("CreateGeom:"); +#if SPAM +Console.WriteLine("CreateGeom:"); +#endif if (_mesh != null) { setMesh(_parent_scene, _mesh); @@ -1944,7 +1946,6 @@ Console.WriteLine(" JointCreateFixed"); if (_parent_scene.needsMeshing(_pbs)) mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); - //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); #if SPAM Console.WriteLine("changesize 1"); #endif @@ -2056,8 +2057,8 @@ Console.WriteLine("changesize 2"); if (IsPhysical) meshlod = _parent_scene.MeshSculptphysicalLOD; - IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); // createmesh returns null when it doesn't mesh. + IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); #if SPAM Console.WriteLine("changeshape needed meshing"); #endif diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 99392cc..7b8a80c 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1723,20 +1723,21 @@ namespace OpenSim.Region.Physics.OdePlugin PhysicsActor result; IMesh mesh = null; - if (needsMeshing(pbs)) - { - try - { - mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); - } - catch(Exception e) - { - m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName); - m_log.Debug(e.ToString()); - mesh = null; - return null; - } - } + // Don't create the mesh here - wait until the mesh data is loaded from the asset store. +// if (needsMeshing(pbs)) +// { +// try +// { +// mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); +// } +// catch(Exception e) +// { +// m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName); +// m_log.Debug(e.ToString()); +// mesh = null; +// return null; +// } +// } result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); @@ -2590,7 +2591,9 @@ namespace OpenSim.Region.Physics.OdePlugin { if (!(_taintedPrimH.Contains(taintedprim))) { -//Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.m_primName); +#if SPAM +Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); +#endif _taintedPrimH.Add(taintedprim); // HashSet for searching _taintedPrimL.Add(taintedprim); // List for ordered readout } -- cgit v1.1 From f75f906e3560b076105ab9551263617e084d6393 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jul 2011 03:13:05 +0100 Subject: minor: remove whitespace to trigger another build --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 56e3b7e..27bf942 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -844,7 +844,6 @@ namespace OpenSim.Region.Physics.OdePlugin return; } - // if (IsPhysical && Body == (IntPtr) 0) // { // Recreate the body -- cgit v1.1 From d31e0a67f7d7c2b1882a2030fe01d5d2ee32ad2a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jul 2011 03:26:22 +0100 Subject: temporarily fix the build break with building the OdePlugin tests assembly. This needs to be fixed properly. --- OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index a7f8baa..fbd1574 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs @@ -31,17 +31,18 @@ using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; +using OpenSim.Region.Physics.OdePlugin; using log4net; using System.Reflection; -namespace OpenSim.Region.Physics.OdePlugin +namespace OpenSim.Region.Physics.OdePlugin.Tests { [TestFixture] public class ODETestClass { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private OdePlugin cbt; + private OpenSim.Region.Physics.OdePlugin.OdePlugin cbt; private PhysicsScene ps; private IMeshingPlugin imp; -- cgit v1.1 From 3e456163dd284fa04ab17465041a1a27f7b632b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jul 2011 22:13:15 +0100 Subject: Port implementation of llCastRay() from Aurora. I haven't been able to test this since the viewer won't parse the llCastRay() function. Maybe some activation cap is missing. Could wait until it is activated by default in the viewer. --- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 24 ++- .../Physics/OdePlugin/ODERayCastRequestManager.cs | 92 +++++++++--- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 28 ++++ .../Shared/Api/Implementation/LSL_Api.cs | 166 +++++++++++++++++++-- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 5 +- .../Shared/Api/Runtime/LSL_Constants.cs | 16 ++ 6 files changed, 298 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 13ea084..0de4626 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -37,6 +37,18 @@ namespace OpenSim.Region.Physics.Manager public delegate void physicsCrash(); public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); + public delegate void RayCallback(List list); + + /// + /// Contact result from a raycast. + /// + public struct ContactResult + { + public Vector3 Pos; + public float Depth; + public uint ConsumerID; + public Vector3 Normal; + } public abstract class PhysicsScene { @@ -61,7 +73,6 @@ namespace OpenSim.Region.Physics.Manager } } - public abstract void Initialise(IMesher meshmerizer, IConfigSource config); public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); @@ -225,6 +236,17 @@ namespace OpenSim.Region.Physics.Manager retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); } + public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) + { + if (retMethod != null) + retMethod(new List()); + } + + public virtual List RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) + { + return new List(); + } + private class NullPhysicsScene : PhysicsScene { private static int m_workIndicator; diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs index ba77dae..6c2bdde 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs @@ -45,11 +45,16 @@ namespace OpenSim.Region.Physics.OdePlugin public class ODERayCastRequestManager { /// - /// Pending Raycast Requests + /// Pending raycast requests /// protected List m_PendingRequests = new List(); /// + /// Pending ray requests + /// + protected List m_PendingRayRequests = new List(); + + /// /// Scene that created this object. /// private OdeScene m_scene; @@ -96,6 +101,29 @@ namespace OpenSim.Region.Physics.OdePlugin } /// + /// Queues a raycast + /// + /// Origin of Ray + /// Ray normal + /// Ray length + /// + /// Return method to send the results + public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) + { + lock (m_PendingRequests) + { + ODERayRequest req = new ODERayRequest(); + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = count; + + m_PendingRayRequests.Add(req); + } + } + + /// /// Process all queued raycast requests /// /// Time in MS the raycasts took to process. @@ -112,15 +140,23 @@ namespace OpenSim.Region.Physics.OdePlugin if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast RayCast(reqs[i]); // if there isn't anyone to send results } - /* - foreach (ODERayCastRequest req in m_PendingRequests) + + m_PendingRequests.Clear(); + } + } + + lock (m_PendingRayRequests) + { + if (m_PendingRayRequests.Count > 0) + { + ODERayRequest[] reqs = m_PendingRayRequests.ToArray(); + for (int i = 0; i < reqs.Length; i++) { - if (req.callbackMethod != null) // quick optimization here, don't raycast - RayCast(req); // if there isn't anyone to send results to - + if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast + RayCast(reqs[i]); // if there isn't anyone to send results } - */ - m_PendingRequests.Clear(); + + m_PendingRayRequests.Clear(); } } @@ -146,7 +182,6 @@ namespace OpenSim.Region.Physics.OdePlugin // Remove Ray d.GeomDestroy(ray); - // Define default results bool hitYN = false; uint hitConsumerID = 0; @@ -177,6 +212,31 @@ namespace OpenSim.Region.Physics.OdePlugin req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); } + /// + /// Method that actually initiates the raycast + /// + /// + private void RayCast(ODERayRequest req) + { + // Create the ray + IntPtr ray = d.CreateRay(m_scene.space, req.length); + d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); + + // Collide test + d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); + + // Remove Ray + d.GeomDestroy(ray); + + // Find closest contact and object. + lock (m_contactResults) + { + // Return results + if (req.callbackMethod != null) + req.callbackMethod(m_contactResults); + } + } + // This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { @@ -342,10 +402,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_contactResults.Add(collisionresult); } } - - } - } /// @@ -365,11 +422,12 @@ namespace OpenSim.Region.Physics.OdePlugin public RaycastCallback callbackMethod; } - public struct ContactResult + public struct ODERayRequest { - public Vector3 Pos; - public float Depth; - public uint ConsumerID; + public Vector3 Origin; public Vector3 Normal; + public int Count; + public float length; + public RayCallback callbackMethod; } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 7b8a80c..ba8cba4 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -3736,6 +3736,34 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } } + public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) + { + if (retMethod != null) + { + m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); + } + } + + public override List RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) + { + ContactResult[] ourResults = null; + RayCallback retMethod = delegate(List results) + { + ourResults = new ContactResult[results.Count]; + results.CopyTo(ourResults, 0); + }; + int waitTime = 0; + m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); + while (ourResults == null && waitTime < 1000) + { + Thread.Sleep(1); + waitTime++; + } + if (ourResults == null) + return new List (); + return new List(ourResults); + } + #if USE_DRAWSTUFF // Keyboard callback public void command(int cmd) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fd6d64c..c8bce60 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10309,51 +10309,191 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return rq.ToString(); } + public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) + { + m_host.AddScriptLPS(1); + + Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); + Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); + Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); + + int count = 0; +// int detectPhantom = 0; + int dataFlags = 0; + int rejectTypes = 0; + + for (int i = 0; i < options.Length; i += 2) + { + if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) + { + count = options.GetLSLIntegerItem(i + 1); + } +// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) +// { +// detectPhantom = options.GetLSLIntegerItem(i + 1); +// } + else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) + { + dataFlags = options.GetLSLIntegerItem(i + 1); + } + else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) + { + rejectTypes = options.GetLSLIntegerItem(i + 1); + } + } + + LSL_List list = new LSL_List(); + List results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); + + double distance = Util.GetDistanceTo(startvector, endvector); + + if (distance == 0) + distance = 0.001; + + Vector3 posToCheck = startvector; + ITerrainChannel channel = World.RequestModuleInterface(); + + bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); + bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); + bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); + bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); + + for (float i = 0; i <= distance; i += 0.1f) + { + posToCheck = startvector + (dir * (i / (float)distance)); + + if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) + { + ContactResult result = new ContactResult(); + result.ConsumerID = 0; + result.Depth = 0; + result.Normal = Vector3.Zero; + result.Pos = posToCheck; + results.Add(result); + checkTerrain = false; + } + + if (checkAgents) + { + World.ForEachScenePresence(delegate(ScenePresence sp) + { + if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) + { + ContactResult result = new ContactResult (); + result.ConsumerID = sp.LocalId; + result.Depth = 0; + result.Normal = Vector3.Zero; + result.Pos = posToCheck; + results.Add(result); + } + }); + } + } + + int refcount = 0; + foreach (ContactResult result in results) + { + if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) + == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) + continue; + + ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); + + if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) + entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents + + if (entity == null) + { + list.Add(UUID.Zero); + + if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) + list.Add(0); + + list.Add(result.Pos); + + if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) + list.Add(result.Normal); + + continue; //Can't find it, so add UUID.Zero + } + + /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && + ((ISceneChildEntity)intersection.obj).PhysActor == null) + continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects + + if (entity is SceneObjectPart) + { + if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) + { + if (!checkPhysical) + continue; + } + else + { + if (!checkNonPhysical) + continue; + } + } + + refcount++; + if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) + list.Add(((SceneObjectPart)entity).ParentGroup.UUID); + else + list.Add(entity.UUID); + + if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) + { + if (entity is SceneObjectPart) + list.Add(((SceneObjectPart)entity).LinkNum); + else + list.Add(0); + } + + list.Add(result.Pos); + + if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) + list.Add(result.Normal); + } + + list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED + + return list; + } + #region Not Implemented // // Listing the unimplemented lsl functions here, please move // them from this region as they are completed // - public void llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) - { - m_host.AddScriptLPS(1); - NotImplemented("llCastRay"); - - } public void llGetEnv(LSL_String name) { m_host.AddScriptLPS(1); NotImplemented("llGetEnv"); - } public void llGetSPMaxMemory() { m_host.AddScriptLPS(1); NotImplemented("llGetSPMaxMemory"); - } public void llGetUsedMemory() { m_host.AddScriptLPS(1); NotImplemented("llGetUsedMemory"); - } - public void llRegionSayTo( LSL_Key target, LSL_Integer channel, LSL_String msg ) + public void llRegionSayTo(LSL_Key target, LSL_Integer channel, LSL_String msg) { m_host.AddScriptLPS(1); NotImplemented("llRegionSayTo"); - } - public void llScriptProfiler( LSL_Integer flags ) + public void llScriptProfiler(LSL_Integer flags) { m_host.AddScriptLPS(1); NotImplemented("llScriptProfiler"); - } public void llSetSoundQueueing(int queue) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 654ea81..27f9c84 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -60,6 +60,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llBase64ToString(string str); void llBreakAllLinks(); void llBreakLink(int linknum); + LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options); LSL_Integer llCeil(double f); void llClearCameraParams(); LSL_Integer llClearPrimMedia(LSL_Integer face); @@ -404,7 +405,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llXorBase64StringsCorrect(string str1, string str2); void print(string str); - void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); - LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); + void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); + LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 9377cda..3f90788 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -593,5 +593,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; + + public static readonly LSLInteger RC_REJECT_TYPES = 2; + public static readonly LSLInteger RC_DATA_FLAGS = 4; + public static readonly LSLInteger RC_MAX_HITS = 8; + public static readonly LSLInteger RC_DETECT_PHANTOM = 16; + + public static readonly LSLInteger RC_REJECT_AGENTS = 2; + public static readonly LSLInteger RC_REJECT_PHYSICAL = 4; + public static readonly LSLInteger RC_REJECT_NONPHYSICAL = 8; + public static readonly LSLInteger RC_REJECT_LAND = 16; + + public static readonly LSLInteger RC_GET_NORMAL = 2; + public static readonly LSLInteger RC_GET_ROOT_KEY = 4; + public static readonly LSLInteger RC_GET_LINK_NUM = 8; + + public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 1; } } -- cgit v1.1 From bf1b8397bb6a8dad5eba89b44c46412bbb948edd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jul 2011 23:35:06 +0100 Subject: Add a warning to URI config in GridCommon.ini.example not to add a slash to the end. Tidy up GridCommon.ini.example --- OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index f15f8f6..b5cbcbb 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -68,7 +68,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring { m_scene = scene; - m_scene.AddCommand(this, "monitor report", "monitor report", "Returns a variety of statistics about the current region and/or simulator", -- cgit v1.1 From 5158ec0913357261dfa6db821c3b19a788b88266 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jul 2011 00:24:55 +0100 Subject: Add experimental module to check status of services that the simulator is connected to. Currently disabled. --- .../Framework/Monitoring/MonitorServicesModule.cs | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs new file mode 100644 index 0000000..d49face --- /dev/null +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs @@ -0,0 +1,119 @@ +/* + * 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.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Framework.Monitoring +{ + /// + /// An experimental module to return data on services used by the simulator. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MonitorServicesModule")] + public class MonitorServicesModule : ISharedRegionModule + { + protected Scene m_scene; + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public string Name { get { return "Services Health Monitoring Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + if (m_scene == null) + { + m_scene = scene; + +// m_scene.AddCommand(this, "monitor services", +// "monitor services", +// "Returns the status of services used by the simulator. Experimental.", +// HandleMonitorServices); + } + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + } + + protected void HandleMonitorServices(string module, string[] args) + { + MainConsole.Instance.Output(GenerateServicesReport()); + } + + protected string GenerateServicesReport() + { + StringBuilder sb = new StringBuilder(); + sb.Append("This is an experimental module. Please don't rely on these results\n"); + sb.Append("Asset service: "); + + try + { + CheckAssetService(); + sb.Append("OK"); + } + catch (Exception e) + { + sb.AppendFormat("FAIL ({0})", e.Message); + } + + return sb.ToString(); + } + + protected void CheckAssetService() + { + // Try to fetch an asset that will not exist (and hence avoid hitting cache) + m_scene.AssetService.Get(UUID.Random().ToString()); + } + } +} \ No newline at end of file -- cgit v1.1 From 08dc07dc7691ce8ee3c81528bb45b9fdfc603a68 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jul 2011 00:48:36 +0100 Subject: refactor: Move all callers of the obsoleted SychronousRestObjectPoster.BeginPostObject() to the identical SynchronousRestObjectRequester.MakeRequest() --- .../CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 7 ++++--- .../Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 321b38b..8d055d4 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -173,9 +173,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { if (m_RestURL != "") { - m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); + m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); - List msglist = SynchronousRestObjectPoster.BeginPostObject>( + List msglist + = SynchronousRestObjectRequester.MakeRequest>( "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); if (msglist == null) @@ -203,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if ((im.offline != 0) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { - bool success = SynchronousRestObjectPoster.BeginPostObject( + bool success = SynchronousRestObjectRequester.MakeRequest( "POST", m_RestURL+"/SaveMessage/", im); if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index d18ac0a..2187449 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule info.channel = channel; info.uri = uri; - bool success = SynchronousRestObjectPoster.BeginPostObject( + bool success = SynchronousRestObjectRequester.MakeRequest( "POST", m_ServerURI+"/RegisterChannel/", info); if (!success) @@ -125,7 +125,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule if (m_Channels.ContainsKey(itemID)) { - bool success = SynchronousRestObjectPoster.BeginPostObject( + bool success = SynchronousRestObjectRequester.MakeRequest( "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]); if (!success) -- cgit v1.1 From b55076990c3ba27bc9a0ca716031928fae887deb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 14 Jul 2011 12:38:35 -0700 Subject: fix duplication of physical objects for physics engines that care about the initial value of localID --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 905acd6..343a8fd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1463,16 +1463,16 @@ namespace OpenSim.Region.Framework.Scenes // Need to duplicate the physics actor as well if (part.PhysActor != null && userExposed) { - PrimitiveBaseShape pbs = part.Shape; + PrimitiveBaseShape pbs = newPart.Shape; newPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - part.LocalId, - string.Format("{0}/{1}", part.Name, part.UUID), + newPart.LocalId, + string.Format("{0}/{1}", newPart.Name, newPart.UUID), pbs, - part.AbsolutePosition, - part.Scale, - part.RotationOffset, + newPart.AbsolutePosition, + newPart.Scale, + newPart.RotationOffset, part.PhysActor.IsPhysical); newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); -- cgit v1.1 From e9dbe54ab1217e4310b0e7e014516363237e2a21 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Jul 2011 20:07:59 +0100 Subject: Fix some local id issues in physics glue --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 4 +-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 32 ++++++++++++++-------- .../BasicPhysicsPlugin/BasicPhysicsScene.cs | 8 +----- .../BulletDotNETPlugin/BulletDotNETScene.cs | 7 +---- .../Region/Physics/BulletXPlugin/BulletXPlugin.cs | 8 +----- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 19 +++++-------- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 8 +----- .../Region/Physics/OdePlugin/Tests/ODETestClass.cs | 2 +- OpenSim/Region/Physics/POSPlugin/POSScene.cs | 8 +----- OpenSim/Region/Physics/PhysXPlugin/PhysXScene.cs | 8 +----- 10 files changed, 36 insertions(+), 68 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 343a8fd..0fbd746 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1467,13 +1467,13 @@ namespace OpenSim.Region.Framework.Scenes newPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - newPart.LocalId, string.Format("{0}/{1}", newPart.Name, newPart.UUID), pbs, newPart.AbsolutePosition, newPart.Scale, newPart.RotationOffset, - part.PhysActor.IsPhysical); + part.PhysActor.IsPhysical, + newPart.LocalId); newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e9571aa..7604510 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1588,17 +1588,23 @@ namespace OpenSim.Region.Framework.Scenes // or flexible if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) { -// m_log.DebugFormat("[SCENE OBJECT PART]: Creating PhysActor for {0} {1} {2}", Name, LocalId, UUID); - - PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( - LocalId, - string.Format("{0}/{1}", Name, UUID), - Shape, - AbsolutePosition, - Scale, - RotationOffset, - RigidBody); - + try + { + PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( + string.Format("{0}/{1}", Name, UUID), + Shape, + AbsolutePosition, + Scale, + RotationOffset, + RigidBody, + m_localId); + PhysActor.SetMaterial(Material); + } + catch + { + m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); + PhysActor = null; + } // Basic Physics returns null.. joy joy joy. if (PhysActor != null) { @@ -4446,7 +4452,9 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition, Scale, RotationOffset, - UsePhysics); + UsePhysics, + m_localId); + PhysActor.SetMaterial(Material); pa = PhysActor; if (pa != null) diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index b6e1cb4..6c9d9ab 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -84,13 +84,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin */ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation) - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { return null; } diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs index 6df213d..0d1bd82 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs @@ -213,12 +213,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin return newPrim; } - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation) - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical) + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { PhysicsActor result; IMesh mesh = null; diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index e2a6a2e..df62dbc 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -626,13 +626,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin } public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, OpenMetaverse.Vector3 position, - OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation) - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, OpenMetaverse.Vector3 position, - OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation, bool isPhysical) + OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation, bool isPhysical, uint localid) { PhysicsActor result; diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 0de4626..28ace34 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -88,15 +88,16 @@ namespace OpenSim.Region.Physics.Manager public abstract void RemovePrim(PhysicsActor prim); + //public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + // Vector3 size, Quaternion rotation); //To be removed - Actually removed! + public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation); //To be removed - public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical); + Vector3 size, Quaternion rotation, bool isPhysical, uint localid); public virtual PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { - PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical); + PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid); if (ret != null) ret.LocalID = localID; @@ -284,13 +285,7 @@ namespace OpenSim.Region.Physics.Manager */ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation) //To be removed - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddPrim({0},{1})", position, size); return PhysicsActor.Null; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index ba8cba4..6fda32d 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1708,13 +1708,7 @@ namespace OpenSim.Region.Physics.OdePlugin } public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation) //To be removed - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { #if SPAM m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index fbd1574..2ea810f 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.Physics.OdePlugin.Tests Vector3 position = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 128f); Vector3 size = new Vector3(0.5f, 0.5f, 0.5f); Quaternion rot = Quaternion.Identity; - PhysicsActor prim = ps.AddPrimShape("CoolShape", newcube, position, size, rot, true); + PhysicsActor prim = ps.AddPrimShape("CoolShape", newcube, position, size, rot, true, 0); OdePrim oprim = (OdePrim)prim; OdeScene pscene = (OdeScene) ps; diff --git a/OpenSim/Region/Physics/POSPlugin/POSScene.cs b/OpenSim/Region/Physics/POSPlugin/POSScene.cs index c3f5040..2f24a50 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSScene.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSScene.cs @@ -91,13 +91,7 @@ namespace OpenSim.Region.Physics.POSPlugin */ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation) - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { POSPrim prim = new POSPrim(); prim.Position = position; diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXScene.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXScene.cs index 4de4b01..beb3404 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXScene.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXScene.cs @@ -108,13 +108,7 @@ namespace OpenSim.Region.Physics.PhysXPlugin } public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation) //To be removed - { - return AddPrimShape(primName, pbs, position, size, rotation, false); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { return AddPrim(position, size, rotation); } -- cgit v1.1 From 3e5b2d52ff7e9fd0c968608c4a705740f51b9bc2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jul 2011 22:58:29 +0100 Subject: minor: method doc for baked texture uploading --- .../ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 17 +++++++++++++++-- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 3 ++- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index b11210a..8db4e67 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -331,14 +331,22 @@ namespace OpenSim.Region.ClientStack.Linden } } + /// + /// Handle a request from the client for a Uri to upload a baked texture. + /// + /// + /// + /// + /// + /// + /// The upload response if the request is successful, null otherwise. public string UploadBakedTexture(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { try { - // m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + - // m_regionName); +// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + m_regionName); string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); @@ -374,6 +382,11 @@ namespace OpenSim.Region.ClientStack.Linden return null; } + /// + /// Called when a baked texture has been successfully uploaded by a client. + /// + /// + /// public void BakedTextureUploaded(UUID assetID, byte[] data) { // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 1955e5b..75dbeb8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -180,8 +180,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } /// - /// Set appearance data (textureentry and slider settings) received from the client + /// Set appearance data (texture asset IDs and slider settings) received from the client /// + /// /// /// public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) -- cgit v1.1 From 0ee7a5ee81437f7fb81814b1694c00cb5a206bda Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jul 2011 23:36:32 +0100 Subject: If object is an attachment, make llGetVel() return the avatar's speed rather than the object's own zero speed. As per http://opensimulator.org/mantis/view.php?id=5575 --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 1 - .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 520d794..1e09610 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -566,7 +566,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { - m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c8bce60..7759b0a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2214,7 +2214,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetVel() { m_host.AddScriptLPS(1); - return new LSL_Vector(m_host.Velocity.X, m_host.Velocity.Y, m_host.Velocity.Z); + + Vector3 vel; + + if (m_host.IsAttachment) + { + ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.AttachedAvatar); + vel = avatar.Velocity; + } + else + { + vel = m_host.Velocity; + } + + return new LSL_Vector(vel.X, vel.Y, vel.Z); } public LSL_Vector llGetAccel() @@ -10021,8 +10034,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; } } + return ret; } + SceneObjectPart obj = World.GetSceneObjectPart(key); if (obj != null) { -- cgit v1.1 From a9ba9d4a9ee2515d2541fc536525ebed3d101606 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jul 2011 23:51:55 +0100 Subject: change async parameter name in AddLocalPacketHandler since it becomes a reserved keyword in .net 5 Also adds some method doc. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c176c2b..8414f8b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -574,22 +574,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP return result; } + /// + /// Add a handler for the given packet type. + /// + /// The packet is handled on its own thread. If packets must be handled in the order in which thye + /// are received then please us ethe synchronous version of this method. + /// + /// + /// true if the handler was added. This is currently always the case. public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler) { return AddLocalPacketHandler(packetType, handler, true); } - public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool async) + /// + /// Add a handler for the given packet type. + /// + /// + /// + /// + /// If true, when the packet is received it is handled on its own thread rather than on the main inward bound + /// packet handler thread. This vastly increases respnosiveness but some packets need to be handled + /// synchronously. + /// + /// true if the handler was added. This is currently always the case. + public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) { bool result = false; lock (m_packetHandlers) { if (!m_packetHandlers.ContainsKey(packetType)) { - m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = async }); + m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync }); result = true; } } + return result; } -- cgit v1.1 From 7247ca16447e962d0f8281e0ed4f163ea4e06b96 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 00:08:11 +0100 Subject: use constants in llGetObjectDetails() rather than magic numbers --- .../Shared/Api/Implementation/LSL_Api.cs | 43 +++++++++++----------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7759b0a..26969a5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2523,10 +2523,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// negative (indicating end-relative) and may be inverted, /// i.e. end < start. /// - public LSL_String llDeleteSubString(string src, int start, int end) { - m_host.AddScriptLPS(1); // Normalize indices (if negative). @@ -2606,10 +2604,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// which case it is end-relative. The index may exceed either /// string bound, with the result being a concatenation. /// - public LSL_String llInsertString(string dest, int index, string src) { - m_host.AddScriptLPS(1); // Normalize indices (if negative). @@ -9996,6 +9992,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List llGetObjectDetails(string id, LSL_List args) { m_host.AddScriptLPS(1); + LSL_List ret = new LSL_List(); UUID key = new UUID(); if (UUID.TryParse(id, out key)) @@ -10006,30 +10003,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { foreach (object o in args.Data) { - switch (o.ToString()) + switch (int.Parse(o.ToString())) { - case "1": + case ScriptBaseClass.OBJECT_NAME: ret.Add(new LSL_String(av.Firstname + " " + av.Lastname)); break; - case "2": + case ScriptBaseClass.OBJECT_DESC: ret.Add(new LSL_String("")); break; - case "3": + case ScriptBaseClass.OBJECT_POS: ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); break; - case "4": + case ScriptBaseClass.OBJECT_ROT: ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); break; - case "5": + case ScriptBaseClass.OBJECT_VELOCITY: ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); break; - case "6": + case ScriptBaseClass.OBJECT_OWNER: ret.Add(new LSL_String(id)); break; - case "7": + case ScriptBaseClass.OBJECT_GROUP: ret.Add(new LSL_String(UUID.Zero.ToString())); break; - case "8": + case ScriptBaseClass.OBJECT_CREATOR: ret.Add(new LSL_String(UUID.Zero.ToString())); break; } @@ -10043,37 +10040,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { foreach (object o in args.Data) { - switch (o.ToString()) + switch (int.Parse(o.ToString())) { - case "1": + case ScriptBaseClass.OBJECT_NAME: ret.Add(new LSL_String(obj.Name)); break; - case "2": + case ScriptBaseClass.OBJECT_DESC: ret.Add(new LSL_String(obj.Description)); break; - case "3": + case ScriptBaseClass.OBJECT_POS: ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); break; - case "4": + case ScriptBaseClass.OBJECT_ROT: ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); break; - case "5": + case ScriptBaseClass.OBJECT_VELOCITY: ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); break; - case "6": + case ScriptBaseClass.OBJECT_OWNER: ret.Add(new LSL_String(obj.OwnerID.ToString())); break; - case "7": + case ScriptBaseClass.OBJECT_GROUP: ret.Add(new LSL_String(obj.GroupID.ToString())); break; - case "8": + case ScriptBaseClass.OBJECT_CREATOR: ret.Add(new LSL_String(obj.CreatorID.ToString())); break; } } + return ret; } } + return new LSL_List(); } -- cgit v1.1 From 18652eb87ef0613b66664059581f991448d76af4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 01:36:27 +0100 Subject: Fix physics proxy regeneration when a mesh with more than one submesh is resized Addresses http://opensimulator.org/mantis/view.php?id=5584 --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 12 ++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 ++++++++- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 5 ++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0fbd746..fd5f1b0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2662,13 +2662,18 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetChildPart(localID); if (part != null) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, localID, part.Scale, scale); + part.IgnoreUndoUpdate = true; + if (scale.X > m_scene.m_maxNonphys) scale.X = m_scene.m_maxNonphys; if (scale.Y > m_scene.m_maxNonphys) scale.Y = m_scene.m_maxNonphys; if (scale.Z > m_scene.m_maxNonphys) scale.Z = m_scene.m_maxNonphys; + if (part.PhysActor != null && part.PhysActor.IsPhysical) { if (scale.X > m_scene.m_maxPhys) @@ -2780,7 +2785,14 @@ namespace OpenSim.Region.Framework.Scenes newSize.Z *= z; obPart.Resize(newSize); obPart.UpdateOffSet(currentpos); + + if (obPart.PhysActor != null) + { + obPart.PhysActor.Size = newSize; + m_scene.PhysicsScene.AddPhysicsActorTaint(obPart.PhysActor); + } } + obPart.IgnoreUndoUpdate = false; obPart.StoreUndoState(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7604510..96dc82b8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2839,6 +2839,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void Resize(Vector3 scale) { +// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); + StoreUndoState(); m_shape.Scale = scale; @@ -2976,6 +2978,11 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Sets sculpt and mesh data, and tells the physics engine to process the change. + /// + /// Texture id of the mesh. XXX: Redundant since this is also in AssetBase + /// The mesh itself. public void SculptTextureCallback(UUID textureID, AssetBase texture) { if (m_shape.SculptEntry) @@ -4613,7 +4620,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CheckSculptAndLoad() { -// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); +// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); if (ParentGroup.IsDeleted) return; diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 5ca5f20..5413aa8 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -303,6 +303,10 @@ namespace OpenSim.Region.Physics.Meshing private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { +// m_log.DebugFormat( +// "[MESH]: Creating physics proxy for {0}, shape {1}", +// primName, (OpenMetaverse.SculptType)primShape.SculptType); + PrimMesh primMesh; PrimMesher.SculptMesh sculptMesh; @@ -668,7 +672,6 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - key = GetMeshKey(primShape, size, lod); if (m_uniqueMeshes.TryGetValue(key, out mesh)) return mesh; diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 27bf942..b3045bd 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2284,6 +2284,7 @@ Console.WriteLine("changeshape not need meshing"); if (value.IsFinite()) { _size = value; +// m_log.DebugFormat("[PHYSICS]: Set size on {0} to {1}", Name, value); } else { -- cgit v1.1 From da7340b9fb6a6f4468310958671f429f133e8424 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 01:42:56 +0100 Subject: If resized shape is a mesh/sculpt, leave it to the mesh asset callback to trigger the physics actor taint. In the last commit, the fix was made by updating all the child prim physics actors with the new size rather than just the root part. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fd5f1b0..9c307a3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2789,7 +2789,10 @@ namespace OpenSim.Region.Framework.Scenes if (obPart.PhysActor != null) { obPart.PhysActor.Size = newSize; - m_scene.PhysicsScene.AddPhysicsActorTaint(obPart.PhysActor); + + // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. + if (((OpenMetaverse.SculptType)obPart.Shape.SculptType) != SculptType.Mesh) + m_scene.PhysicsScene.AddPhysicsActorTaint(obPart.PhysActor); } } @@ -2800,7 +2803,10 @@ namespace OpenSim.Region.Framework.Scenes if (part.PhysActor != null) { part.PhysActor.Size = prevScale; - m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); + + // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. + if (((OpenMetaverse.SculptType)part.Shape.SculptType) != SculptType.Mesh) + m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); } part.IgnoreUndoUpdate = false; -- cgit v1.1 From 50bd48542c379f0ce0cec85eb412ded16c819434 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 02:44:00 +0100 Subject: Add very basic test for resizing a scene object with one prim --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 3 +- .../Scenes/Tests/SceneObjectResizeTests.cs | 67 ++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9c307a3..34e44e5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -617,9 +617,10 @@ namespace OpenSim.Region.Framework.Scenes finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; - return finalScale; + return finalScale; } + public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) { // We got a request from the inner_scene to raytrace along the Ray hRay diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs new file mode 100644 index 0000000..3865329 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -0,0 +1,67 @@ +/* + * 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.Reflection; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + /// + /// Basic scene object resize tests + /// + [TestFixture] + public class SceneObjectResizeTests + { + /// + /// Test resizing an object + /// + [Test] + public void TestResizeSceneObject() + { + TestHelper.InMethod(); + //log4net.Config.XmlConfigurator.Configure(); + + Scene scene = SceneSetupHelpers.SetupScene(); + SceneObjectGroup g1 = SceneSetupHelpers.AddSceneObject(scene).ParentGroup; + + g1.GroupResize(new Vector3(2, 3, 4), g1.LocalId); + + SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID); + + Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); + Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); + Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); + } + } +} \ No newline at end of file -- cgit v1.1 From 27fae36a21ff39e9bd413a3f4a4bb544f40bb4e1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 02:53:36 +0100 Subject: remove the need to supply SceneObjectGroup.GroupResize() with a localId. This is utterly pointless scene we already know which sog we're dealing with. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 261 +++++++++++---------- .../Scenes/Tests/SceneObjectResizeTests.cs | 2 +- 3 files changed, 133 insertions(+), 132 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 7ec7ea3..0e5ffc0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1234,7 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { - group.GroupResize(scale, localID); + group.GroupResize(scale); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 34e44e5..f7ef0b4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2658,164 +2658,165 @@ namespace OpenSim.Region.Framework.Scenes } } - public void GroupResize(Vector3 scale, uint localID) + /// + /// Resize the entire group of prims. + /// + /// + public void GroupResize(Vector3 scale) { - SceneObjectPart part = GetChildPart(localID); - if (part != null) - { // m_log.DebugFormat( -// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, localID, part.Scale, scale); +// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, localID, RootPart.Scale, scale); + + RootPart.IgnoreUndoUpdate = true; - part.IgnoreUndoUpdate = true; + if (scale.X > m_scene.m_maxNonphys) + scale.X = m_scene.m_maxNonphys; + if (scale.Y > m_scene.m_maxNonphys) + scale.Y = m_scene.m_maxNonphys; + if (scale.Z > m_scene.m_maxNonphys) + scale.Z = m_scene.m_maxNonphys; - if (scale.X > m_scene.m_maxNonphys) - scale.X = m_scene.m_maxNonphys; - if (scale.Y > m_scene.m_maxNonphys) - scale.Y = m_scene.m_maxNonphys; - if (scale.Z > m_scene.m_maxNonphys) - scale.Z = m_scene.m_maxNonphys; + if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) + { + if (scale.X > m_scene.m_maxPhys) + scale.X = m_scene.m_maxPhys; + if (scale.Y > m_scene.m_maxPhys) + scale.Y = m_scene.m_maxPhys; + if (scale.Z > m_scene.m_maxPhys) + scale.Z = m_scene.m_maxPhys; + } - if (part.PhysActor != null && part.PhysActor.IsPhysical) - { - if (scale.X > m_scene.m_maxPhys) - scale.X = m_scene.m_maxPhys; - if (scale.Y > m_scene.m_maxPhys) - scale.Y = m_scene.m_maxPhys; - if (scale.Z > m_scene.m_maxPhys) - scale.Z = m_scene.m_maxPhys; - } - float x = (scale.X / part.Scale.X); - float y = (scale.Y / part.Scale.Y); - float z = (scale.Z / part.Scale.Z); + float x = (scale.X / RootPart.Scale.X); + float y = (scale.Y / RootPart.Scale.Y); + float z = (scale.Z / RootPart.Scale.Z); - SceneObjectPart[] parts; - if (x > 1.0f || y > 1.0f || z > 1.0f) + SceneObjectPart[] parts; + if (x > 1.0f || y > 1.0f || z > 1.0f) + { + parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) + SceneObjectPart obPart = parts[i]; + if (obPart.UUID != m_rootPart.UUID) { - SceneObjectPart obPart = parts[i]; - if (obPart.UUID != m_rootPart.UUID) - { - obPart.IgnoreUndoUpdate = true; - Vector3 oldSize = new Vector3(obPart.Scale); + obPart.IgnoreUndoUpdate = true; + Vector3 oldSize = new Vector3(obPart.Scale); - float f = 1.0f; - float a = 1.0f; + float f = 1.0f; + float a = 1.0f; - if (part.PhysActor != null && part.PhysActor.IsPhysical) + if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) + { + if (oldSize.X * x > m_scene.m_maxPhys) { - if (oldSize.X * x > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.X; - a = f / x; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Y * y > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.Y; - a = f / y; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Z * z > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.Z; - a = f / z; - x *= a; - y *= a; - z *= a; - } + f = m_scene.m_maxPhys / oldSize.X; + a = f / x; + x *= a; + y *= a; + z *= a; } - else + if (oldSize.Y * y > m_scene.m_maxPhys) { - if (oldSize.X * x > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.X; - a = f / x; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Y * y > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.Y; - a = f / y; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Z * z > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.Z; - a = f / z; - x *= a; - y *= a; - z *= a; - } + f = m_scene.m_maxPhys / oldSize.Y; + a = f / y; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Z * z > m_scene.m_maxPhys) + { + f = m_scene.m_maxPhys / oldSize.Z; + a = f / z; + x *= a; + y *= a; + z *= a; + } + } + else + { + if (oldSize.X * x > m_scene.m_maxNonphys) + { + f = m_scene.m_maxNonphys / oldSize.X; + a = f / x; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Y * y > m_scene.m_maxNonphys) + { + f = m_scene.m_maxNonphys / oldSize.Y; + a = f / y; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Z * z > m_scene.m_maxNonphys) + { + f = m_scene.m_maxNonphys / oldSize.Z; + a = f / z; + x *= a; + y *= a; + z *= a; } - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); } + obPart.IgnoreUndoUpdate = false; + obPart.StoreUndoState(); } } + } - Vector3 prevScale = part.Scale; - prevScale.X *= x; - prevScale.Y *= y; - prevScale.Z *= z; - part.Resize(prevScale); + Vector3 prevScale = RootPart.Scale; + prevScale.X *= x; + prevScale.Y *= y; + prevScale.Z *= z; + RootPart.Resize(prevScale); - parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) + parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart obPart = parts[i]; + obPart.IgnoreUndoUpdate = true; + if (obPart.UUID != m_rootPart.UUID) { - SceneObjectPart obPart = parts[i]; - obPart.IgnoreUndoUpdate = true; - if (obPart.UUID != m_rootPart.UUID) + Vector3 currentpos = new Vector3(obPart.OffsetPosition); + currentpos.X *= x; + currentpos.Y *= y; + currentpos.Z *= z; + Vector3 newSize = new Vector3(obPart.Scale); + newSize.X *= x; + newSize.Y *= y; + newSize.Z *= z; + obPart.Resize(newSize); + obPart.UpdateOffSet(currentpos); + + if (obPart.PhysActor != null) { - Vector3 currentpos = new Vector3(obPart.OffsetPosition); - currentpos.X *= x; - currentpos.Y *= y; - currentpos.Z *= z; - Vector3 newSize = new Vector3(obPart.Scale); - newSize.X *= x; - newSize.Y *= y; - newSize.Z *= z; - obPart.Resize(newSize); - obPart.UpdateOffSet(currentpos); - - if (obPart.PhysActor != null) - { - obPart.PhysActor.Size = newSize; + obPart.PhysActor.Size = newSize; - // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. - if (((OpenMetaverse.SculptType)obPart.Shape.SculptType) != SculptType.Mesh) - m_scene.PhysicsScene.AddPhysicsActorTaint(obPart.PhysActor); - } + // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. + if (((OpenMetaverse.SculptType)obPart.Shape.SculptType) != SculptType.Mesh) + m_scene.PhysicsScene.AddPhysicsActorTaint(obPart.PhysActor); } - - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); } - if (part.PhysActor != null) - { - part.PhysActor.Size = prevScale; + obPart.IgnoreUndoUpdate = false; + obPart.StoreUndoState(); + } - // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. - if (((OpenMetaverse.SculptType)part.Shape.SculptType) != SculptType.Mesh) - m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); - } + if (RootPart.PhysActor != null) + { + RootPart.PhysActor.Size = prevScale; - part.IgnoreUndoUpdate = false; - part.StoreUndoState(); - HasGroupChanged = true; - m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); - ScheduleGroupForTerseUpdate(); + // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. + if (((OpenMetaverse.SculptType)RootPart.Shape.SculptType) != SculptType.Mesh) + m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); } + + RootPart.IgnoreUndoUpdate = false; + RootPart.StoreUndoState(); + HasGroupChanged = true; + RootPart.TriggerScriptChangedEvent(Changed.SCALE); + ScheduleGroupForTerseUpdate(); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 3865329..627f294 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Scene scene = SceneSetupHelpers.SetupScene(); SceneObjectGroup g1 = SceneSetupHelpers.AddSceneObject(scene).ParentGroup; - g1.GroupResize(new Vector3(2, 3, 4), g1.LocalId); + g1.GroupResize(new Vector3(2, 3, 4)); SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID); -- cgit v1.1 From 2b339b7d2b1e860af2ea2a873797a70bc257bf6f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 02:56:54 +0100 Subject: minor: remove mono compiler warnings --- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 2 +- OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | 2 +- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index c82cfd2..d687e6a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure if (!(client.Scene is Scene)) return; - Scene scene = (Scene)(client.Scene); +// Scene scene = (Scene)(client.Scene); GridInstantMessage im = null; if (m_PendingLures.TryGetValue(lureID, out im)) diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index 079e1b6..dee0ad4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs @@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile if (!(s is Scene)) return; - Scene scene = (Scene)s; +// Scene scene = (Scene)s; string profileUrl = String.Empty; string aboutText = String.Empty; diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 66fbcb9..b714f2b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -810,18 +810,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) remoteClient.SendBulkUpdateInventory(item); + return null; } - for (int i = 0 ; i < objlist.Count ; i++ ) + for (int i = 0 ; i < objlist.Count; i++) { group = objlist[i]; - Vector3 storedPosition = group.AbsolutePosition; +// Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); } + group.RootPart.FromFolderID = item.Folder; // If it's rezzed in world, select it. Much easier to @@ -833,6 +835,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (SceneObjectPart child in group.Parts) child.CreateSelected = true; } + group.ResetIDs(); if (attachment) -- cgit v1.1 From 3fc12e72245c81075fb7a584c40aa49a10a3b458 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:02:28 +0100 Subject: Eliminate the pointless textured id argument to SculptTextureCallback --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 96dc82b8..a55e07a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1731,7 +1731,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart sop = (SceneObjectPart)sender; if (sop != null) - sop.SculptTextureCallback(asset.FullID, asset); + sop.SculptTextureCallback(asset); } } @@ -2979,11 +2979,10 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Sets sculpt and mesh data, and tells the physics engine to process the change. + /// Set sculpt and mesh data, and tell the physics engine to process the change. /// - /// Texture id of the mesh. XXX: Redundant since this is also in AssetBase /// The mesh itself. - public void SculptTextureCallback(UUID textureID, AssetBase texture) + public void SculptTextureCallback(AssetBase texture) { if (m_shape.SculptEntry) { @@ -3009,16 +3008,6 @@ namespace OpenSim.Region.Framework.Scenes } } -// /// -// /// -// /// -// /// -// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) -// { -// m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); -// } - - /// /// Send a full update to the client for the given part /// @@ -4631,9 +4620,11 @@ namespace OpenSim.Region.Framework.Scenes if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero) { // check if a previously decoded sculpt map has been cached + // We don't read the file here - the meshmerizer will do that later. + // TODO: Could we simplify the meshmerizer code by reading and setting the data here? if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString()))) { - SculptTextureCallback(Shape.SculptTexture, null); + SculptTextureCallback(null); } else { -- cgit v1.1 From c82f19e41cbfcf4eb8bb3691d1653eeceaa6a8ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:06:30 +0100 Subject: fix build break from last commit --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f7ef0b4..0b474b5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3345,7 +3345,7 @@ namespace OpenSim.Region.Framework.Scenes if (sop != null) { if (asset != null) - sop.SculptTextureCallback(asset.FullID, asset); + sop.SculptTextureCallback(asset); } } -- cgit v1.1 From 982e71b6b88ccbb884044d4b1c350b27c4877060 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:08:28 +0100 Subject: eliminate unused and redundant SceneObjectGroup.AssetReceived() --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0b474b5..8ffe84b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3333,23 +3333,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Handle an asset received asynchronously from the asset service. - /// - /// - /// - /// - protected void AssetReceived(string id, Object sender, AssetBase asset) - { - SceneObjectPart sop = (SceneObjectPart)sender; - - if (sop != null) - { - if (asset != null) - sop.SculptTextureCallback(asset); - } - } - - /// /// Set the user group to which this scene object belongs. /// /// -- cgit v1.1 From 6f9b8557192ea5fe65e4dc7416809a4d1affa954 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:16:24 +0100 Subject: refactor: remove pointless sender != null tests, etc, in AssetReceived, since the method called always belongs to the object that generated the request --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a55e07a..697dd0e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1711,7 +1711,8 @@ namespace OpenSim.Region.Framework.Scenes { if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) { - m_parentGroup.Scene.AssetService.Get(dupe.m_shape.SculptTexture.ToString(), dupe, AssetReceived); + ParentGroup.Scene.AssetService.Get( + dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived); } bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); @@ -1725,14 +1726,16 @@ namespace OpenSim.Region.Framework.Scenes return dupe; } + /// + /// Called back by asynchronous asset fetch. + /// + /// ID of asset received + /// Register + /// protected void AssetReceived(string id, Object sender, AssetBase asset) { if (asset != null) - { - SceneObjectPart sop = (SceneObjectPart)sender; - if (sop != null) - sop.SculptTextureCallback(asset); - } + SculptTextureCallback(asset); } public static SceneObjectPart Create() -- cgit v1.1 From 0f9882db5b6708864924218f713863ff7b9ded47 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:24:36 +0100 Subject: minor: add a log warning if a sculpt/mesh async asset request returns no data --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 697dd0e..5035317 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1736,6 +1736,10 @@ namespace OpenSim.Region.Framework.Scenes { if (asset != null) SculptTextureCallback(asset); + else + m_log.WarnFormat( + "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", + Name, LocalId, id); } public static SceneObjectPart Create() -- cgit v1.1 From df2a59d31b1ae21f99c1b18976b8d799b935a762 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:30:14 +0100 Subject: refactor: make SceneObjectGroup.GroupScale() a property rather than a mehod --- .../Caps/ObjectCaps/UploadObjectAssetModule.cs | 10 ++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 61 ++++++++++++---------- 2 files changed, 38 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 15ed3b3..8189518 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -129,7 +129,7 @@ namespace OpenSim.Region.ClientStack.Linden /// - /// Parses ad request + /// Parses add request /// /// /// @@ -312,11 +312,11 @@ namespace OpenSim.Region.ClientStack.Linden primFace.RepeatV = face.ScaleT; primFace.TexMapType = (MappingType) (face.MediaFlags & 6); } + pbs.TextureEntry = tmp.GetBytes(); prim.Shape = pbs; prim.Scale = obj.Scale; - SceneObjectGroup grp = new SceneObjectGroup(); grp.SetRootPart(prim); @@ -339,8 +339,8 @@ namespace OpenSim.Region.ClientStack.Linden m_scene.AddSceneObject(grp); grp.AbsolutePosition = obj.Position; } + allparts[i] = grp; - } for (int j = 1; j < allparts.Length; j++) @@ -351,7 +351,9 @@ namespace OpenSim.Region.ClientStack.Linden } rootGroup.ScheduleGroupForFullUpdate(); - pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); + pos + = m_scene.GetNewRezLocation( + Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false); responsedata["int_response_code"] = 200; //501; //410; //404; responsedata["content_type"] = "text/plain"; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8ffe84b..7aa7831 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -236,6 +236,38 @@ namespace OpenSim.Region.Framework.Scenes get { return m_rootPart.RotationOffset; } } + public Vector3 GroupScale + { + get + { + Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); + Vector3 maxScale = Vector3.Zero; + Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + Vector3 partscale = part.Scale; + Vector3 partoffset = part.OffsetPosition; + + minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; + minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; + minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; + + maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; + maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; + maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; + } + + finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; + finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; + finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; + + return finalScale; + } + } + public UUID GroupID { get { return m_rootPart.GroupID; } @@ -592,35 +624,6 @@ namespace OpenSim.Region.Framework.Scenes //ScheduleGroupForFullUpdate(); } - public Vector3 GroupScale() - { - Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); - Vector3 maxScale = Vector3.Zero; - Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); - - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - { - SceneObjectPart part = parts[i]; - Vector3 partscale = part.Scale; - Vector3 partoffset = part.OffsetPosition; - - minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; - minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; - minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; - - maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; - maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; - maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; - } - - finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; - finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; - finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; - - return finalScale; - } - public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) { // We got a request from the inner_scene to raytrace along the Ray hRay -- cgit v1.1 From 4b5a6b655becd5162054bc53365fdcd9c7ed1772 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 03:52:30 +0100 Subject: add test for resizing one part in a group --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Scenes/Tests/SceneObjectResizeTests.cs | 35 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 0e5ffc0..df6908a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1210,7 +1210,7 @@ namespace OpenSim.Region.Framework.Scenes #region Client Event handlers /// - /// + /// Update the scale of an individual prim. /// /// /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 627f294..95ecfc6 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -63,5 +63,40 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); } + + /// + /// Test resizing an individual part in a scene object. + /// + [Test] + public void TestResizeSceneObjectPart() + { + TestHelper.InMethod(); + //log4net.Config.XmlConfigurator.Configure(); + + Scene scene = SceneSetupHelpers.SetupScene(); + + SceneObjectGroup g1 = SceneSetupHelpers.CreateSceneObject(2, UUID.Zero); + g1.RootPart.Scale = new Vector3(2, 3, 4); + g1.Parts[1].Scale = new Vector3(5, 6, 7); + + scene.AddSceneObject(g1); + + SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID); + + g1Post.Resize(new Vector3(8, 9, 10), g1Post.Parts[1].LocalId); + + SceneObjectGroup g1PostPost = scene.GetSceneObjectGroup(g1.UUID); + + SceneObjectPart g1RootPart = g1PostPost.RootPart; + SceneObjectPart g1ChildPart = g1PostPost.Parts[1]; + + Assert.That(g1RootPart.Scale.X, Is.EqualTo(2)); + Assert.That(g1RootPart.Scale.Y, Is.EqualTo(3)); + Assert.That(g1RootPart.Scale.Z, Is.EqualTo(4)); + + Assert.That(g1ChildPart.Scale.X, Is.EqualTo(8)); + Assert.That(g1ChildPart.Scale.Y, Is.EqualTo(9)); + Assert.That(g1ChildPart.Scale.Z, Is.EqualTo(10)); + } } } \ No newline at end of file -- cgit v1.1 From 2b68ac4ba31205a55f53f1b69629dd9ebbd66ef6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 04:22:57 +0100 Subject: refactor: Push all part resize code down into SceneObjectPart.Resize() --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 9 ++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 50 ---------------------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 27 +++++++++++- .../Scenes/Tests/SceneObjectResizeTests.cs | 2 +- 4 files changed, 32 insertions(+), 56 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index df6908a..00d25c2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1217,12 +1217,13 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient) { - SceneObjectGroup group = GetGroupByPrim(localID); - if (group != null) + SceneObjectPart part = GetSceneObjectPart(localID); + + if (part != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)) { - group.Resize(scale, localID); + part.Resize(scale); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7aa7831..477b3e3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2612,56 +2612,6 @@ namespace OpenSim.Region.Framework.Scenes #region Resize /// - /// Resize the given part - /// - /// - /// - public void Resize(Vector3 scale, uint localID) - { - if (scale.X > m_scene.m_maxNonphys) - scale.X = m_scene.m_maxNonphys; - if (scale.Y > m_scene.m_maxNonphys) - scale.Y = m_scene.m_maxNonphys; - if (scale.Z > m_scene.m_maxNonphys) - scale.Z = m_scene.m_maxNonphys; - - SceneObjectPart part = GetChildPart(localID); - if (part != null) - { - part.Resize(scale); - if (part.PhysActor != null) - { - if (part.PhysActor.IsPhysical) - { - if (scale.X > m_scene.m_maxPhys) - scale.X = m_scene.m_maxPhys; - if (scale.Y > m_scene.m_maxPhys) - scale.Y = m_scene.m_maxPhys; - if (scale.Z > m_scene.m_maxPhys) - scale.Z = m_scene.m_maxPhys; - } - part.PhysActor.Size = scale; - m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); - } - //if (part.UUID != m_rootPart.UUID) - - HasGroupChanged = true; - part.TriggerScriptChangedEvent(Changed.SCALE); - ScheduleGroupForFullUpdate(); - - //if (part.UUID == m_rootPart.UUID) - //{ - //if (m_rootPart.PhysActor != null) - //{ - //m_rootPart.PhysActor.Size = - //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); - //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); - //} - //} - } - } - - /// /// Resize the entire group of prims. /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5035317..ffde68e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2846,6 +2846,13 @@ namespace OpenSim.Region.Framework.Scenes /// public void Resize(Vector3 scale) { + if (scale.X > ParentGroup.Scene.m_maxNonphys) + scale.X = ParentGroup.Scene.m_maxNonphys; + if (scale.Y > ParentGroup.Scene.m_maxNonphys) + scale.Y = ParentGroup.Scene.m_maxNonphys; + if (scale.Z > ParentGroup.Scene.m_maxNonphys) + scale.Z = ParentGroup.Scene.m_maxNonphys; + // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); StoreUndoState(); @@ -2855,9 +2862,27 @@ namespace OpenSim.Region.Framework.Scenes // need to reinsert the sculpt data into the shape, since the physics engine deletes it when done to // save memory if (PhysActor != null) - CheckSculptAndLoad(); + { + if (PhysActor.IsPhysical) + { + if (scale.X > ParentGroup.Scene.m_maxPhys) + scale.X = ParentGroup.Scene.m_maxPhys; + if (scale.Y > ParentGroup.Scene.m_maxPhys) + scale.Y = ParentGroup.Scene.m_maxPhys; + if (scale.Z > ParentGroup.Scene.m_maxPhys) + scale.Z = ParentGroup.Scene.m_maxPhys; + } + + PhysActor.Size = scale; + + if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + CheckSculptAndLoad(); + else + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + } ParentGroup.HasGroupChanged = true; + TriggerScriptChangedEvent(Changed.SCALE); ScheduleFullUpdate(); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 95ecfc6..7ec36b8 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID); - g1Post.Resize(new Vector3(8, 9, 10), g1Post.Parts[1].LocalId); + g1Post.Parts[1].Resize(new Vector3(8, 9, 10)); SceneObjectGroup g1PostPost = scene.GetSceneObjectGroup(g1.UUID); -- cgit v1.1 From 122745fe1c17ff0862f5a0cb2f97e8abf8d67cb6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 04:28:49 +0100 Subject: refactor: replace scale limiting code with more elegant Math.Min calls --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ffde68e..f5b8daf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2846,12 +2846,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void Resize(Vector3 scale) { - if (scale.X > ParentGroup.Scene.m_maxNonphys) - scale.X = ParentGroup.Scene.m_maxNonphys; - if (scale.Y > ParentGroup.Scene.m_maxNonphys) - scale.Y = ParentGroup.Scene.m_maxNonphys; - if (scale.Z > ParentGroup.Scene.m_maxNonphys) - scale.Z = ParentGroup.Scene.m_maxNonphys; + scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); + scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); + scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); @@ -2865,12 +2862,9 @@ namespace OpenSim.Region.Framework.Scenes { if (PhysActor.IsPhysical) { - if (scale.X > ParentGroup.Scene.m_maxPhys) - scale.X = ParentGroup.Scene.m_maxPhys; - if (scale.Y > ParentGroup.Scene.m_maxPhys) - scale.Y = ParentGroup.Scene.m_maxPhys; - if (scale.Z > ParentGroup.Scene.m_maxPhys) - scale.Z = ParentGroup.Scene.m_maxPhys; + scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); + scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); + scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); } PhysActor.Size = scale; -- cgit v1.1 From 9a80adf33ae0d255d923d33f5b6abac540efcd52 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 04:49:21 +0100 Subject: remove now unncessary parts of SceneObjectGroup.Resize() --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 26 +++++----------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 477b3e3..7662874 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2611,6 +2611,7 @@ namespace OpenSim.Region.Framework.Scenes #region Resize + /// /// Resize the entire group of prims. /// @@ -2712,6 +2713,7 @@ namespace OpenSim.Region.Framework.Scenes z *= a; } } + obPart.IgnoreUndoUpdate = false; obPart.StoreUndoState(); } @@ -2729,47 +2731,29 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart obPart = parts[i]; obPart.IgnoreUndoUpdate = true; + if (obPart.UUID != m_rootPart.UUID) { Vector3 currentpos = new Vector3(obPart.OffsetPosition); currentpos.X *= x; currentpos.Y *= y; currentpos.Z *= z; + Vector3 newSize = new Vector3(obPart.Scale); newSize.X *= x; newSize.Y *= y; newSize.Z *= z; + obPart.Resize(newSize); obPart.UpdateOffSet(currentpos); - - if (obPart.PhysActor != null) - { - obPart.PhysActor.Size = newSize; - - // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. - if (((OpenMetaverse.SculptType)obPart.Shape.SculptType) != SculptType.Mesh) - m_scene.PhysicsScene.AddPhysicsActorTaint(obPart.PhysActor); - } } obPart.IgnoreUndoUpdate = false; obPart.StoreUndoState(); } - if (RootPart.PhysActor != null) - { - RootPart.PhysActor.Size = prevScale; - - // If we're a sculpt wait for the trigger when the sculpt texture is retrieved. - if (((OpenMetaverse.SculptType)RootPart.Shape.SculptType) != SculptType.Mesh) - m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); - } - RootPart.IgnoreUndoUpdate = false; RootPart.StoreUndoState(); - HasGroupChanged = true; - RootPart.TriggerScriptChangedEvent(Changed.SCALE); - ScheduleGroupForTerseUpdate(); } #endregion -- cgit v1.1 From f5ddf37112d4881243e3350d5df898c6b2bb02ae Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jul 2011 05:23:21 +0100 Subject: Replace ifs in SOG.GroupResize() with Math.Min() Also fiddle a bit with undo. This is not currently working properly, though to be fair it also didn't appear to work in 0.7.1.1 either (at least for resize). Will get some more attention soon. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 20 +++++++------------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 18 +++++++++++++++++- 3 files changed, 25 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 00d25c2..bdb7f95 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -569,6 +569,7 @@ namespace OpenSim.Region.Framework.Scenes if (primId != UUID.Zero) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId); + if (part != null) part.Redo(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7662874..ce5db5f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2623,21 +2623,15 @@ namespace OpenSim.Region.Framework.Scenes RootPart.IgnoreUndoUpdate = true; - if (scale.X > m_scene.m_maxNonphys) - scale.X = m_scene.m_maxNonphys; - if (scale.Y > m_scene.m_maxNonphys) - scale.Y = m_scene.m_maxNonphys; - if (scale.Z > m_scene.m_maxNonphys) - scale.Z = m_scene.m_maxNonphys; + scale.X = Math.Min(scale.X, Scene.m_maxNonphys); + scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); + scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) { - if (scale.X > m_scene.m_maxPhys) - scale.X = m_scene.m_maxPhys; - if (scale.Y > m_scene.m_maxPhys) - scale.Y = m_scene.m_maxPhys; - if (scale.Z > m_scene.m_maxPhys) - scale.Z = m_scene.m_maxPhys; + scale.X = Math.Min(scale.X, Scene.m_maxPhys); + scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); + scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); } float x = (scale.X / RootPart.Scale.X); @@ -2715,7 +2709,6 @@ namespace OpenSim.Region.Framework.Scenes } obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); } } } @@ -2753,6 +2746,7 @@ namespace OpenSim.Region.Framework.Scenes } RootPart.IgnoreUndoUpdate = false; + RootPart.StoreUndoState(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f5b8daf..6b9607c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3687,6 +3687,8 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentGroup != null) { +// m_log.DebugFormat("[SCENE OBJECT PART]: Storing undo state for {0} {1}", Name, LocalId); + lock (m_undo) { if (m_undo.Count > 0) @@ -3705,11 +3707,18 @@ namespace OpenSim.Region.Framework.Scenes m_undo.Push(nUndo); } - } } } +// else +// { +// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); +// } } +// else +// { +// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); +// } } public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) @@ -4179,11 +4188,14 @@ namespace OpenSim.Region.Framework.Scenes if (m_undo.Count > 0) { UndoState nUndo = null; + if (m_parentGroup.GetSceneMaxUndo() > 0) { nUndo = new UndoState(this); } + UndoState goback = m_undo.Pop(); + if (goback != null) { goback.PlaybackState(this); @@ -4196,6 +4208,8 @@ namespace OpenSim.Region.Framework.Scenes public void Redo() { +// m_log.DebugFormat("[SCENE OBJECT PART]: Handling redo request for {0} {1}", Name, LocalId); + lock (m_redo) { if (m_parentGroup.GetSceneMaxUndo() > 0) @@ -4204,7 +4218,9 @@ namespace OpenSim.Region.Framework.Scenes m_undo.Push(nUndo); } + UndoState gofwd = m_redo.Pop(); + if (gofwd != null) gofwd.PlayfwdState(this); } -- cgit v1.1 From e9a739f45fdc464b19ad520c3efcb202d8bd5458 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Jul 2011 01:33:57 +0100 Subject: refactor: group all the undo/redo code in SOP into one place for easier code reading --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 121 +++++++++++---------- 1 file changed, 62 insertions(+), 59 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 6b9607c..253326e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -414,7 +414,6 @@ namespace OpenSim.Region.Framework.Scenes CreateSelected = true; TrimPermissions(); - //m_undo = new UndoStack(ParentGroup.GetSceneMaxUndo()); m_inventory = new SceneObjectPartInventory(this); } @@ -1621,19 +1620,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void ClearUndoState() - { - lock (m_undo) - { - m_undo.Clear(); - } - lock (m_redo) - { - m_redo.Clear(); - } - StoreUndoState(); - } - public byte ConvertScriptUintToByte(uint indata) { byte outdata = (byte)TextureAnimFlags.NONE; @@ -3721,6 +3707,68 @@ namespace OpenSim.Region.Framework.Scenes // } } + public void Undo() + { +// m_log.DebugFormat("[SCENE OBJECT PART]: Handling undo request for {0} {1}", Name, LocalId); + + lock (m_undo) + { + if (m_undo.Count > 0) + { + UndoState nUndo = null; + + if (m_parentGroup.GetSceneMaxUndo() > 0) + { + nUndo = new UndoState(this); + } + + UndoState goback = m_undo.Pop(); + + if (goback != null) + { + goback.PlaybackState(this); + if (nUndo != null) + m_redo.Push(nUndo); + } + } + } + } + + public void Redo() + { +// m_log.DebugFormat("[SCENE OBJECT PART]: Handling redo request for {0} {1}", Name, LocalId); + + lock (m_redo) + { + if (m_parentGroup.GetSceneMaxUndo() > 0) + { + UndoState nUndo = new UndoState(this); + + m_undo.Push(nUndo); + } + + UndoState gofwd = m_redo.Pop(); + + if (gofwd != null) + gofwd.PlayfwdState(this); + } + } + + public void ClearUndoState() + { + lock (m_undo) + { + m_undo.Clear(); + } + + lock (m_redo) + { + m_redo.Clear(); + } + + StoreUndoState(); + } + public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) { // In this case we're using a sphere with a radius of the largest dimension of the prim @@ -4181,51 +4229,6 @@ namespace OpenSim.Region.Framework.Scenes _nextOwnerMask &= (uint)PermissionMask.All; } - public void Undo() - { - lock (m_undo) - { - if (m_undo.Count > 0) - { - UndoState nUndo = null; - - if (m_parentGroup.GetSceneMaxUndo() > 0) - { - nUndo = new UndoState(this); - } - - UndoState goback = m_undo.Pop(); - - if (goback != null) - { - goback.PlaybackState(this); - if (nUndo != null) - m_redo.Push(nUndo); - } - } - } - } - - public void Redo() - { -// m_log.DebugFormat("[SCENE OBJECT PART]: Handling redo request for {0} {1}", Name, LocalId); - - lock (m_redo) - { - if (m_parentGroup.GetSceneMaxUndo() > 0) - { - UndoState nUndo = new UndoState(this); - - m_undo.Push(nUndo); - } - - UndoState gofwd = m_redo.Pop(); - - if (gofwd != null) - gofwd.PlayfwdState(this); - } - } - public void UpdateExtraParam(ushort type, bool inUse, byte[] data) { m_shape.ReadInUpdateExtraParam(type, inUse, data); -- cgit v1.1 From 3f8e571b7887758514645c46b2b26d7c3fc82e45 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Jul 2011 02:01:12 +0100 Subject: Use a standard generic system stack for the undo/redo stacks instead of our own homebrew. system stack also uses an array, so no performance penalty. Also exposes undo count and adds a test assertion for correct undo count after resize --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 ++++++++++++++-- .../Framework/Scenes/Tests/SceneObjectResizeTests.cs | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 253326e..a1200ee 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -287,8 +287,8 @@ namespace OpenSim.Region.Framework.Scenes private string m_sitAnimation = "SIT"; private string m_text = String.Empty; private string m_touchName = String.Empty; - private readonly UndoStack m_undo = new UndoStack(5); - private readonly UndoStack m_redo = new UndoStack(5); + private readonly Stack m_undo = new Stack(5); + private readonly Stack m_redo = new Stack(5); private UUID _creatorID; private bool m_passTouches; @@ -3707,6 +3707,18 @@ namespace OpenSim.Region.Framework.Scenes // } } + /// + /// Return number of undos on the stack. Here temporarily pending a refactor. + /// + public int UndoCount + { + get + { + lock (m_undo) + return m_undo.Count; + } + } + public void Undo() { // m_log.DebugFormat("[SCENE OBJECT PART]: Handling undo request for {0} {1}", Name, LocalId); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 7ec36b8..6dbac3c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -62,6 +62,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); + + Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1)); } /// -- cgit v1.1 From aec3b58a5775b70de278c950f300a0f7e6787ec2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Jul 2011 02:06:06 +0100 Subject: use standard sdk stack in terrain model rather than OpenSim.Framework.UndoStack. remove OpenSim.Framework.UndoStack --- OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 9c7b2fa..c832520 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain private ITerrainChannel m_revert; private Scene m_scene; private volatile bool m_tainted; - private readonly UndoStack m_undo = new UndoStack(5); + private readonly Stack m_undo = new Stack(5); #region ICommandableModule Members -- cgit v1.1 From 6fc74b36d1d0f7dcd6f013893c3189a3f989431c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Jul 2011 04:54:21 +0100 Subject: Make various tweaks to undo code in an effort to get things working better. Undo rotation and position appear to be working. Resizing a single prim appears to be working, though the undo has to be done twice. Resizing a group of prims still does not work properly - possibly because in the UndoState we don't store a knowledge of when we're resizing a whole group rather than individual prims. This needs to be addressed. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 27 ++++++- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1 + .../Region/Framework/Scenes/SceneObjectGroup.cs | 58 +++++++++++--- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 92 +++++++++++++-------- .../Scenes/Tests/SceneObjectResizeTests.cs | 2 +- OpenSim/Region/Framework/Scenes/UndoState.cs | 93 ++++++++++++++++++++-- 6 files changed, 217 insertions(+), 56 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8414f8b..fa35bd8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11242,6 +11242,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { + // Do this once since fetch parts creates a new array. + SceneObjectPart[] parts = part.ParentGroup.Parts; + for (int j = 0; j < parts.Length; j++) + { + part.StoreUndoState(); + parts[j].IgnoreUndoUpdate = true; + } + // UUID partId = part.UUID; UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; @@ -11257,6 +11265,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimSinglePosition(localId, pos1, this); } break; + case 2: Quaternion rot1 = new Quaternion(block.Data, 0, true); @@ -11267,6 +11276,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimSingleRotation(localId, rot1, this); } break; + case 3: Vector3 rotPos = new Vector3(block.Data, 0); Quaternion rot2 = new Quaternion(block.Data, 12, true); @@ -11279,6 +11289,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this); } break; + case 4: case 20: Vector3 scale4 = new Vector3(block.Data, 0); @@ -11290,8 +11301,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimScale(localId, scale4, this); } break; - case 5: + case 5: Vector3 scale1 = new Vector3(block.Data, 12); Vector3 pos11 = new Vector3(block.Data, 0); @@ -11308,6 +11319,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } break; + case 9: Vector3 pos2 = new Vector3(block.Data, 0); @@ -11315,10 +11327,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerUpdateVector != null) { - handlerUpdateVector(localId, pos2, this); } break; + case 10: Quaternion rot3 = new Quaternion(block.Data, 0, true); @@ -11329,6 +11341,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimRotation(localId, rot3, this); } break; + case 11: Vector3 pos3 = new Vector3(block.Data, 0); Quaternion rot4 = new Quaternion(block.Data, 12, true); @@ -11352,6 +11365,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimGroupScale(localId, scale7, this); } break; + case 13: Vector3 scale2 = new Vector3(block.Data, 12); Vector3 pos4 = new Vector3(block.Data, 0); @@ -11371,6 +11385,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } break; + case 29: Vector3 scale5 = new Vector3(block.Data, 12); Vector3 pos5 = new Vector3(block.Data, 0); @@ -11388,6 +11403,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } break; + case 21: Vector3 scale6 = new Vector3(block.Data, 12); Vector3 pos6 = new Vector3(block.Data, 0); @@ -11404,13 +11420,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } break; + default: - m_log.Debug("[CLIENT] MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); + m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); break; } + + for (int j = 0; j < parts.Length; j++) + parts[j].IgnoreUndoUpdate = false; } } } + return true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index bdb7f95..0a0bde8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -564,6 +564,7 @@ namespace OpenSim.Region.Framework.Scenes part.Undo(); } } + protected internal void HandleRedo(IClientAPI remoteClient, UUID primId) { if (primId != UUID.Zero) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ce5db5f..7254992 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1145,6 +1145,10 @@ namespace OpenSim.Region.Framework.Scenes public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}", +// remoteClient.Name, part.Name, part.LocalId, offsetPos); + part.StoreUndoState(); part.OnGrab(offsetPos, remoteClient); } @@ -2611,17 +2615,14 @@ namespace OpenSim.Region.Framework.Scenes #region Resize - /// /// Resize the entire group of prims. /// /// public void GroupResize(Vector3 scale) { -// m_log.DebugFormat( -// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, localID, RootPart.Scale, scale); - - RootPart.IgnoreUndoUpdate = true; +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); scale.X = Math.Min(scale.X, Scene.m_maxNonphys); scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); @@ -2647,7 +2648,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart obPart = parts[i]; if (obPart.UUID != m_rootPart.UUID) { - obPart.IgnoreUndoUpdate = true; +// obPart.IgnoreUndoUpdate = true; Vector3 oldSize = new Vector3(obPart.Scale); float f = 1.0f; @@ -2663,6 +2664,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } + if (oldSize.Y * y > m_scene.m_maxPhys) { f = m_scene.m_maxPhys / oldSize.Y; @@ -2671,6 +2673,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } + if (oldSize.Z * z > m_scene.m_maxPhys) { f = m_scene.m_maxPhys / oldSize.Z; @@ -2690,6 +2693,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } + if (oldSize.Y * y > m_scene.m_maxNonphys) { f = m_scene.m_maxNonphys / oldSize.Y; @@ -2698,6 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } + if (oldSize.Z * z > m_scene.m_maxNonphys) { f = m_scene.m_maxNonphys / oldSize.Z; @@ -2708,7 +2713,7 @@ namespace OpenSim.Region.Framework.Scenes } } - obPart.IgnoreUndoUpdate = false; +// obPart.IgnoreUndoUpdate = false; } } } @@ -2723,7 +2728,7 @@ namespace OpenSim.Region.Framework.Scenes for (int i = 0; i < parts.Length; i++) { SceneObjectPart obPart = parts[i]; - obPart.IgnoreUndoUpdate = true; +// obPart.IgnoreUndoUpdate = true; if (obPart.UUID != m_rootPart.UUID) { @@ -2738,16 +2743,18 @@ namespace OpenSim.Region.Framework.Scenes newSize.Z *= z; obPart.Resize(newSize); + + obPart.IgnoreUndoUpdate = true; obPart.UpdateOffSet(currentpos); + obPart.IgnoreUndoUpdate = false; } - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); +// obPart.IgnoreUndoUpdate = false; +// obPart.StoreUndoState(); } - RootPart.IgnoreUndoUpdate = false; - - RootPart.StoreUndoState(); +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale); } #endregion @@ -2760,6 +2767,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupPosition(Vector3 pos) { +// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos); + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].StoreUndoState(); @@ -2805,6 +2814,9 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos); + if (part.UUID == m_rootPart.UUID) { UpdateRootPosition(pos); @@ -2824,6 +2836,9 @@ namespace OpenSim.Region.Framework.Scenes /// private void UpdateRootPosition(Vector3 pos) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos); + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].StoreUndoState(); @@ -2868,6 +2883,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupRotationR(Quaternion rot) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot); + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].StoreUndoState(); @@ -2892,6 +2910,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot); + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].StoreUndoState(); @@ -2926,6 +2947,9 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot); + if (part.UUID == m_rootPart.UUID) { UpdateRootRotation(rot); @@ -2947,6 +2971,10 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetChildPart(localID); if (part != null) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}", +// part.Name, part.LocalId, rot); + if (part.UUID == m_rootPart.UUID) { UpdateRootRotation(rot); @@ -2969,6 +2997,10 @@ namespace OpenSim.Region.Framework.Scenes /// private void UpdateRootRotation(Quaternion rot) { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", +// Name, LocalId, rot); + Quaternion axRot = rot; Quaternion oldParentRot = m_rootPart.RotationOffset; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a1200ee..aab83b8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1014,15 +1014,19 @@ namespace OpenSim.Region.Framework.Scenes get { return m_shape; } set { m_shape = value; } } - + + /// + /// Change the scale of this part. + /// public Vector3 Scale { get { return m_shape.Scale; } set { - StoreUndoState(); if (m_shape != null) { + StoreUndoState(); + m_shape.Scale = value; PhysicsActor actor = PhysActor; @@ -1033,11 +1037,16 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentGroup.Scene.PhysicsScene != null) { actor.Size = m_shape.Scale; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); + + if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + CheckSculptAndLoad(); + else + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } } } } + TriggerScriptChangedEvent(Changed.SCALE); } } @@ -2827,8 +2836,12 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Resize this part. + /// Set the scale of this part. /// + /// + /// Unlike the scale property, this checks the new size against scene limits and schedules a full property + /// update to viewers. + /// /// public void Resize(Vector3 scale) { @@ -2836,33 +2849,18 @@ namespace OpenSim.Region.Framework.Scenes scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); -// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); - - StoreUndoState(); - m_shape.Scale = scale; - - // If we're a mesh/sculpt, then we need to tell the physics engine about our new size. To do this, we - // need to reinsert the sculpt data into the shape, since the physics engine deletes it when done to - // save memory - if (PhysActor != null) + if (PhysActor != null && PhysActor.IsPhysical) { - if (PhysActor.IsPhysical) - { - scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); - scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); - scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); - } + scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); + scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); + scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); + } - PhysActor.Size = scale; +// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); - if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) - CheckSculptAndLoad(); - else - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); - } + Scale = scale; ParentGroup.HasGroupChanged = true; - TriggerScriptChangedEvent(Changed.SCALE); ScheduleFullUpdate(); } @@ -3673,8 +3671,6 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentGroup != null) { -// m_log.DebugFormat("[SCENE OBJECT PART]: Storing undo state for {0} {1}", Name, LocalId); - lock (m_undo) { if (m_undo.Count > 0) @@ -3683,15 +3679,29 @@ namespace OpenSim.Region.Framework.Scenes if (last != null) { if (last.Compare(this)) + { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", +// Name, LocalId, m_undo.Count); + return; + } } } +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, initial stack size {2}", +// Name, LocalId, m_undo.Count); + if (m_parentGroup.GetSceneMaxUndo() > 0) { UndoState nUndo = new UndoState(this); m_undo.Push(nUndo); + +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, stack size now {2}", +// Name, LocalId, m_undo.Count); } } } @@ -3703,7 +3713,8 @@ namespace OpenSim.Region.Framework.Scenes } // else // { -// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); // } } @@ -3721,10 +3732,12 @@ namespace OpenSim.Region.Framework.Scenes public void Undo() { -// m_log.DebugFormat("[SCENE OBJECT PART]: Handling undo request for {0} {1}", Name, LocalId); - lock (m_undo) { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", +// Name, LocalId, m_undo.Count); + if (m_undo.Count > 0) { UndoState nUndo = null; @@ -3739,19 +3752,26 @@ namespace OpenSim.Region.Framework.Scenes if (goback != null) { goback.PlaybackState(this); + if (nUndo != null) m_redo.Push(nUndo); } } + +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", +// Name, LocalId, m_undo.Count); } } public void Redo() { -// m_log.DebugFormat("[SCENE OBJECT PART]: Handling redo request for {0} {1}", Name, LocalId); - lock (m_redo) { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", +// Name, LocalId, m_redo.Count); + if (m_parentGroup.GetSceneMaxUndo() > 0) { UndoState nUndo = new UndoState(this); @@ -3763,11 +3783,17 @@ namespace OpenSim.Region.Framework.Scenes if (gofwd != null) gofwd.PlayfwdState(this); + +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", +// Name, LocalId, m_redo.Count); } } public void ClearUndoState() { +// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); + lock (m_undo) { m_undo.Clear(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 6dbac3c..c4047ee 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestResizeSceneObject() { TestHelper.InMethod(); - //log4net.Config.XmlConfigurator.Configure(); +// log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneSetupHelpers.SetupScene(); SceneObjectGroup g1 = SceneSetupHelpers.AddSceneObject(scene).ParentGroup; diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 55e407e..38bbeb0 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -25,6 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; +using System.Reflection; +using log4net; using OpenMetaverse; using OpenSim.Region.Framework.Interfaces; @@ -32,49 +35,80 @@ namespace OpenSim.Region.Framework.Scenes { public class UndoState { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; public Quaternion Rotation = Quaternion.Identity; + /// + /// Constructor. + /// + /// public UndoState(SceneObjectPart part) { if (part != null) { if (part.ParentID == 0) { +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo position {0} for root part", part.ParentGroup.AbsolutePosition); Position = part.ParentGroup.AbsolutePosition; + +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo rotation {0} for root part", part.RotationOffset); Rotation = part.RotationOffset; + +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo scale {0} for root part", part.Shape.Scale); Scale = part.Shape.Scale; } else { +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo position {0} for child part", part.OffsetPosition); Position = part.OffsetPosition; + +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo rotation {0} for child part", part.RotationOffset); Rotation = part.RotationOffset; + +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo scale {0} for child part", part.Shape.Scale); Scale = part.Shape.Scale; } } } + /// + /// Compare the relevant state in the given part to this state. + /// + /// + /// true if both the part's position, rotation and scale match those in this undo state. False otherwise. public bool Compare(SceneObjectPart part) { if (part != null) { if (part.ParentID == 0) { - if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation) + if (Position == part.ParentGroup.AbsolutePosition + && Rotation == part.RotationOffset + && Scale == part.Shape.Scale) return true; else return false; } else { - if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale) + if (Position == part.OffsetPosition + && Rotation == part.RotationOffset + && Scale == part.Shape.Scale) return true; else return false; - } } + return false; } @@ -87,24 +121,64 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0) { if (Position != Vector3.Zero) + { +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing position {0} to {1} for root part {2} {3}", +// part.ParentGroup.AbsolutePosition, Position, part.Name, part.LocalId); + part.ParentGroup.AbsolutePosition = Position; + } + +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", +// part.RotationOffset, Rotation, part.Name, part.LocalId); + part.RotationOffset = Rotation; + if (Scale != Vector3.Zero) + { +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}", +// part.Shape.Scale, Scale, part.Name, part.LocalId); + part.Resize(Scale); + } + part.ParentGroup.ScheduleGroupForTerseUpdate(); } else { if (Position != Vector3.Zero) + { +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}", +// part.OffsetPosition, Position, part.Name, part.LocalId); + part.OffsetPosition = Position; + } + +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}", +// part.RotationOffset, Rotation, part.Name, part.LocalId); + part.UpdateRotation(Rotation); + if (Scale != Vector3.Zero) - part.Resize(Scale); part.ScheduleTerseUpdate(); + { +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}", +// part.Shape.Scale, Scale, part.Name, part.LocalId); + + part.Resize(Scale); + } + + part.ScheduleTerseUpdate(); } - part.Undoing = false; + part.Undoing = false; } } + public void PlayfwdState(SceneObjectPart part) { if (part != null) @@ -115,27 +189,34 @@ namespace OpenSim.Region.Framework.Scenes { if (Position != Vector3.Zero) part.ParentGroup.AbsolutePosition = Position; + if (Rotation != Quaternion.Identity) part.UpdateRotation(Rotation); + if (Scale != Vector3.Zero) part.Resize(Scale); + part.ParentGroup.ScheduleGroupForTerseUpdate(); } else { if (Position != Vector3.Zero) part.OffsetPosition = Position; + if (Rotation != Quaternion.Identity) part.UpdateRotation(Rotation); + if (Scale != Vector3.Zero) part.Resize(Scale); + part.ScheduleTerseUpdate(); } - part.Undoing = false; + part.Undoing = false; } } } + public class LandUndoState { public ITerrainModule m_terrainModule; -- cgit v1.1 From 86f45f6fe716541647e628bc6a29df63330813f8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 01:24:43 +0100 Subject: remove undo state storage in a few places where it's pointless no functional effect - existing bugs still remain --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 -- .../Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index aab83b8..44d7ce3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3803,8 +3803,6 @@ namespace OpenSim.Region.Framework.Scenes { m_redo.Clear(); } - - StoreUndoState(); } public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index c18c93a..8fb9fad 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -102,7 +102,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization sceneObject.AddPart(part); part.LinkNum = linkNum; part.TrimPermissions(); - part.StoreUndoState(); reader.Close(); sr.Close(); } @@ -236,15 +235,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (originalLinkNum != 0) part.LinkNum = originalLinkNum; - part.StoreUndoState(); reader.Close(); sr.Close(); } // Script state may, or may not, exist. Not having any, is NOT // ever a problem. - sceneObject.LoadScriptState(doc); + return sceneObject; } catch (Exception e) -- cgit v1.1 From 430a4aeba8e98b8285ea3ebdf264baf429a55e22 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 03:01:54 +0100 Subject: Fix undo for resizing linksets This involves implementing a boolean in UndoState to signal whether the undo needs to be done for an entire group/linkset or just a single prim Resizing individual components of linksets is still dodgy. Resizing still has to be down twice, since for some reason the client is sending two multiobjectupdate packets on every resize except the very first. This applies to single prims and linksets. Need to look into this. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 37 ++++++++++++------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 23 +++++++----- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 42 +++++++++++++--------- OpenSim/Region/Framework/Scenes/UndoState.cs | 24 ++++++++++--- 4 files changed, 85 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index fa35bd8..4c0b53c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11220,8 +11220,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) { MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; - if (multipleupdate.AgentData.SessionID != SessionId) return false; - // m_log.Debug("new multi update packet " + multipleupdate.ToString()); + + if (multipleupdate.AgentData.SessionID != SessionId) + return false; + +// m_log.DebugFormat( +// "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length); + Scene tScene = (Scene)m_scene; for (int i = 0; i < multipleupdate.ObjectData.Length; i++) @@ -11242,15 +11247,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - // Do this once since fetch parts creates a new array. - SceneObjectPart[] parts = part.ParentGroup.Parts; - for (int j = 0; j < parts.Length; j++) - { - part.StoreUndoState(); - parts[j].IgnoreUndoUpdate = true; - } +// m_log.DebugFormat( +// "[CLIENT]: Processing block {0} type {1} for {2} {3}", +// i, block.Type, part.Name, part.LocalId); + +// // Do this once since fetch parts creates a new array. +// SceneObjectPart[] parts = part.ParentGroup.Parts; +// for (int j = 0; j < parts.Length; j++) +// { +// part.StoreUndoState(); +// parts[j].IgnoreUndoUpdate = true; +// } - // UUID partId = part.UUID; UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; switch (block.Type) @@ -11394,6 +11402,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerUpdatePrimGroupScale != null) { // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + part.StoreUndoState(true); + part.IgnoreUndoUpdate = true; handlerUpdatePrimGroupScale(localId, scale5, this); handlerUpdateVector = OnUpdatePrimGroupPosition; @@ -11401,7 +11411,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP { handlerUpdateVector(localId, pos5, this); } + + part.IgnoreUndoUpdate = false; } + break; case 21: @@ -11426,8 +11439,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; } - for (int j = 0; j < parts.Length; j++) - parts[j].IgnoreUndoUpdate = false; +// for (int j = 0; j < parts.Length; j++) +// parts[j].IgnoreUndoUpdate = false; } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7254992..3bbf76c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2624,6 +2624,8 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); + RootPart.StoreUndoState(true); + scale.X = Math.Min(scale.X, Scene.m_maxNonphys); scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); @@ -2722,16 +2724,20 @@ namespace OpenSim.Region.Framework.Scenes prevScale.X *= x; prevScale.Y *= y; prevScale.Z *= z; + +// RootPart.IgnoreUndoUpdate = true; RootPart.Resize(prevScale); +// RootPart.IgnoreUndoUpdate = false; parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart obPart = parts[i]; -// obPart.IgnoreUndoUpdate = true; if (obPart.UUID != m_rootPart.UUID) { + obPart.IgnoreUndoUpdate = true; + Vector3 currentpos = new Vector3(obPart.OffsetPosition); currentpos.X *= x; currentpos.Y *= y; @@ -2741,12 +2747,11 @@ namespace OpenSim.Region.Framework.Scenes newSize.X *= x; newSize.Y *= y; newSize.Z *= z; - - obPart.Resize(newSize); - obPart.IgnoreUndoUpdate = true; + obPart.Resize(newSize); obPart.UpdateOffSet(currentpos); - obPart.IgnoreUndoUpdate = false; + + obPart.IgnoreUndoUpdate = false; } // obPart.IgnoreUndoUpdate = false; @@ -2769,9 +2774,11 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos); - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].StoreUndoState(); + RootPart.StoreUndoState(true); + +// SceneObjectPart[] parts = m_parts.GetArray(); +// for (int i = 0; i < parts.Length; i++) +// parts[i].StoreUndoState(); if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 44d7ce3..5414cf2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3665,6 +3665,11 @@ namespace OpenSim.Region.Framework.Scenes public void StoreUndoState() { + StoreUndoState(false); + } + + public void StoreUndoState(bool forGroup) + { if (!Undoing) { if (!IgnoreUndoUpdate) @@ -3678,6 +3683,7 @@ namespace OpenSim.Region.Framework.Scenes UndoState last = m_undo.Peek(); if (last != null) { + // TODO: May need to fix for group comparison if (last.Compare(this)) { // m_log.DebugFormat( @@ -3690,12 +3696,12 @@ namespace OpenSim.Region.Framework.Scenes } // m_log.DebugFormat( -// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, initial stack size {2}", -// Name, LocalId, m_undo.Count); +// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", +// Name, LocalId, forGroup, m_undo.Count); if (m_parentGroup.GetSceneMaxUndo() > 0) { - UndoState nUndo = new UndoState(this); + UndoState nUndo = new UndoState(this, forGroup); m_undo.Push(nUndo); @@ -3740,17 +3746,17 @@ namespace OpenSim.Region.Framework.Scenes if (m_undo.Count > 0) { - UndoState nUndo = null; - - if (m_parentGroup.GetSceneMaxUndo() > 0) - { - nUndo = new UndoState(this); - } - UndoState goback = m_undo.Pop(); if (goback != null) { + UndoState nUndo = null; + + if (m_parentGroup.GetSceneMaxUndo() > 0) + { + nUndo = new UndoState(this, goback.ForGroup); + } + goback.PlaybackState(this); if (nUndo != null) @@ -3772,17 +3778,19 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", // Name, LocalId, m_redo.Count); - if (m_parentGroup.GetSceneMaxUndo() > 0) - { - UndoState nUndo = new UndoState(this); - - m_undo.Push(nUndo); - } - UndoState gofwd = m_redo.Pop(); if (gofwd != null) + { + if (m_parentGroup.GetSceneMaxUndo() > 0) + { + UndoState nUndo = new UndoState(this, gofwd.ForGroup); + + m_undo.Push(nUndo); + } + gofwd.PlayfwdState(this); + } // m_log.DebugFormat( // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 38bbeb0..1fa8ee2 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -42,10 +42,16 @@ namespace OpenSim.Region.Framework.Scenes public Quaternion Rotation = Quaternion.Identity; /// + /// Is this undo state for an entire group? + /// + public bool ForGroup; + + /// /// Constructor. /// /// - public UndoState(SceneObjectPart part) + /// True if the undo is for an entire group + public UndoState(SceneObjectPart part, bool forGroup) { if (part != null) { @@ -62,6 +68,8 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[UNDO STATE]: Storing undo scale {0} for root part", part.Shape.Scale); Scale = part.Shape.Scale; + + ForGroup = forGroup; } else { @@ -141,7 +149,10 @@ namespace OpenSim.Region.Framework.Scenes // "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}", // part.Shape.Scale, Scale, part.Name, part.LocalId); - part.Resize(Scale); + if (ForGroup) + part.ParentGroup.GroupResize(Scale); + else + part.Resize(Scale); } part.ParentGroup.ScheduleGroupForTerseUpdate(); @@ -194,7 +205,12 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) - part.Resize(Scale); + { + if (ForGroup) + part.ParentGroup.GroupResize(Scale); + else + part.Resize(Scale); + } part.ParentGroup.ScheduleGroupForTerseUpdate(); } @@ -241,4 +257,4 @@ namespace OpenSim.Region.Framework.Scenes m_terrainModule.UndoTerrain(m_terrainChannel); } } -} +} \ No newline at end of file -- cgit v1.1 From c94dc95844c5a43483a30807353aaebf658b015e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 03:27:16 +0100 Subject: fix undo when resizing of non-root individual prims in a linkset undo resize, rotation and position still needs fixing when only editing root prim of a linkset --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 5 +++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 +++++--- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4c0b53c..a34ad62 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11424,6 +11424,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerUpdatePrimScale = OnUpdatePrimScale; if (handlerUpdatePrimScale != null) { + part.StoreUndoState(false); + part.IgnoreUndoUpdate = true; + // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); handlerUpdatePrimScale(localId, scale6, this); handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; @@ -11431,6 +11434,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { handlerUpdatePrimSinglePosition(localId, pos6, this); } + + part.IgnoreUndoUpdate = false; } break; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 0a0bde8..8e174f5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1291,7 +1291,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) { - group.UpdateSingleRotation(rot,pos, localID); + group.UpdateSingleRotation(rot, pos, localID); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3bbf76c..3adeef1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2815,15 +2815,17 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = GetChildPart(localID); - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].StoreUndoState(); +// SceneObjectPart[] parts = m_parts.GetArray(); +// for (int i = 0; i < parts.Length; i++) +// parts[i].StoreUndoState(); if (part != null) { // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos); + part.StoreUndoState(false); + if (part.UUID == m_rootPart.UUID) { UpdateRootPosition(pos); -- cgit v1.1 From 7c468cda360b9a9382986c3a029b799fd49bf898 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 03:38:22 +0100 Subject: Stop undo of just the root prim position in the linkset from shifting the whole linkset. However, what happens now is that undo just doesn't do anything when the root prim is selected on its own. This requires more code than just fiddling with undo states. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 10 +++++----- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1 - OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ++++++------ OpenSim/Region/Framework/Scenes/UndoState.cs | 11 +++++++++-- 4 files changed, 20 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a34ad62..00115cc 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11224,8 +11224,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (multipleupdate.AgentData.SessionID != SessionId) return false; -// m_log.DebugFormat( -// "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length); + m_log.DebugFormat( + "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length); Scene tScene = (Scene)m_scene; @@ -11247,9 +11247,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { -// m_log.DebugFormat( -// "[CLIENT]: Processing block {0} type {1} for {2} {3}", -// i, block.Type, part.Name, part.LocalId); + m_log.DebugFormat( + "[CLIENT]: Processing block {0} type {1} for {2} {3}", + i, block.Type, part.Name, part.LocalId); // // Do this once since fetch parts creates a new array. // SceneObjectPart[] parts = part.ParentGroup.Parts; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 8e174f5..26857c2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1296,7 +1296,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5414cf2..af836f6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3705,9 +3705,9 @@ namespace OpenSim.Region.Framework.Scenes m_undo.Push(nUndo); -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, stack size now {2}", -// Name, LocalId, m_undo.Count); + m_log.DebugFormat( + "[SCENE OBJECT PART]: Stored undo state for {0} {1}, stack size now {2}", + Name, LocalId, m_undo.Count); } } } @@ -3740,9 +3740,9 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_undo) { -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", -// Name, LocalId, m_undo.Count); + m_log.DebugFormat( + "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", + Name, LocalId, m_undo.Count); if (m_undo.Count > 0) { diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 1fa8ee2..faa1f9e 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -59,7 +59,11 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat( // "[UNDO STATE]: Storing undo position {0} for root part", part.ParentGroup.AbsolutePosition); - Position = part.ParentGroup.AbsolutePosition; + + if (ForGroup) + Position = part.ParentGroup.AbsolutePosition; + else + Position = part.OffsetPosition; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo rotation {0} for root part", part.RotationOffset); @@ -134,7 +138,10 @@ namespace OpenSim.Region.Framework.Scenes // "[UNDO STATE]: Undoing position {0} to {1} for root part {2} {3}", // part.ParentGroup.AbsolutePosition, Position, part.Name, part.LocalId); - part.ParentGroup.AbsolutePosition = Position; + if (ForGroup) + part.ParentGroup.AbsolutePosition = Position; + else + part.OffsetPosition = Position; } // m_log.DebugFormat( -- cgit v1.1 From 4b9ef4f39c420b99568b853b627ad83d253ac2c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 03:44:49 +0100 Subject: Rename UpdatePrimRotation() to UpdatePrimGroupRotation() since this is what it actually does and is more consistent with other method names. --- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ++++++++---- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0104a96..2c71c70 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2718,10 +2718,12 @@ namespace OpenSim.Region.Framework.Scenes { client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition; client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; - client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimRotation; - client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimRotation; + + client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; + client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; + client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; @@ -2845,10 +2847,12 @@ namespace OpenSim.Region.Framework.Scenes { client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimPosition; client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; - client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimRotation; - client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimRotation; + + client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; + client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition; + client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale; client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale; client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 26857c2..d5e0bbb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1297,12 +1297,12 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Update the rotation of a whole group. /// /// /// /// - protected internal void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient) + protected internal void UpdatePrimGroupRotation(uint localID, Quaternion rot, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) @@ -1321,7 +1321,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - protected internal void UpdatePrimRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient) + protected internal void UpdatePrimGroupRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) -- cgit v1.1 From 97f1edfd95176415d0e0b3169467655522334804 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 04:15:27 +0100 Subject: Fix undo of prim group rotation. This isn't that great since I think I broke it a few commits earlier. Undo of rotation of individual prims in a linkset is still broken --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 19 ++++++++---- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 +-- OpenSim/Region/Framework/Scenes/UndoState.cs | 35 ++++++++++++---------- 3 files changed, 34 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3adeef1..aa1f7bc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2895,9 +2895,11 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot); - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].StoreUndoState(); +// SceneObjectPart[] parts = m_parts.GetArray(); +// for (int i = 0; i < parts.Length; i++) +// parts[i].StoreUndoState(); + + m_rootPart.StoreUndoState(true); m_rootPart.UpdateRotation(rot); @@ -2922,9 +2924,12 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot); - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].StoreUndoState(); +// SceneObjectPart[] parts = m_parts.GetArray(); +// for (int i = 0; i < parts.Length; i++) +// parts[i].StoreUndoState(); + + RootPart.StoreUndoState(true); + RootPart.IgnoreUndoUpdate = true; m_rootPart.UpdateRotation(rot); @@ -2939,6 +2944,8 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChanged = true; ScheduleGroupForTerseUpdate(); + + RootPart.IgnoreUndoUpdate = false; } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index af836f6..c3aca15 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3706,8 +3706,8 @@ namespace OpenSim.Region.Framework.Scenes m_undo.Push(nUndo); m_log.DebugFormat( - "[SCENE OBJECT PART]: Stored undo state for {0} {1}, stack size now {2}", - Name, LocalId, m_undo.Count); + "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", + Name, LocalId, forGroup, m_undo.Count); } } } diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index faa1f9e..6f6504c 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Scenes { public class UndoState { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; @@ -57,23 +57,25 @@ namespace OpenSim.Region.Framework.Scenes { if (part.ParentID == 0) { -// m_log.DebugFormat( -// "[UNDO STATE]: Storing undo position {0} for root part", part.ParentGroup.AbsolutePosition); + ForGroup = forGroup; if (ForGroup) Position = part.ParentGroup.AbsolutePosition; else Position = part.OffsetPosition; -// m_log.DebugFormat( -// "[UNDO STATE]: Storing undo rotation {0} for root part", part.RotationOffset); + m_log.DebugFormat( + "[UNDO STATE]: Storing undo position {0} for root part", Position); + Rotation = part.RotationOffset; -// m_log.DebugFormat( -// "[UNDO STATE]: Storing undo scale {0} for root part", part.Shape.Scale); + m_log.DebugFormat( + "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation); + Scale = part.Shape.Scale; - ForGroup = forGroup; + m_log.DebugFormat( + "[UNDO STATE]: Storing undo scale {0} for root part", Scale); } else { @@ -132,23 +134,24 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0) { + m_log.DebugFormat( + "[UNDO STATE]: Undoing position to {0} for root part {1} {2}", + Position, part.Name, part.LocalId); + if (Position != Vector3.Zero) { -// m_log.DebugFormat( -// "[UNDO STATE]: Undoing position {0} to {1} for root part {2} {3}", -// part.ParentGroup.AbsolutePosition, Position, part.Name, part.LocalId); - if (ForGroup) part.ParentGroup.AbsolutePosition = Position; else part.OffsetPosition = Position; } -// m_log.DebugFormat( -// "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", -// part.RotationOffset, Rotation, part.Name, part.LocalId); + m_log.DebugFormat( + "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", + part.RotationOffset, Rotation, part.Name, part.LocalId); - part.RotationOffset = Rotation; + part.UpdateRotation(Rotation); + //part.RotationOffset = Rotation; if (Scale != Vector3.Zero) { -- cgit v1.1 From b2722e984ab99deb01d55cd4c4e9f1a7cb563709 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 04:40:02 +0100 Subject: Fix undo of rotation of single prims in a linkset --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 +++++--- OpenSim/Region/Framework/Scenes/UndoState.cs | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index aa1f7bc..9076d73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2991,6 +2991,9 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}", // part.Name, part.LocalId, rot); + part.StoreUndoState(); + part.IgnoreUndoUpdate = true; + if (part.UUID == m_rootPart.UUID) { UpdateRootRotation(rot); @@ -2998,12 +3001,11 @@ namespace OpenSim.Region.Framework.Scenes } else { - part.IgnoreUndoUpdate = true; part.UpdateRotation(rot); part.OffsetPosition = pos; - part.IgnoreUndoUpdate = false; - part.StoreUndoState(); } + + part.IgnoreUndoUpdate = false; } } diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 6f6504c..68d4cb4 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -79,17 +79,17 @@ namespace OpenSim.Region.Framework.Scenes } else { -// m_log.DebugFormat( -// "[UNDO STATE]: Storing undo position {0} for child part", part.OffsetPosition); Position = part.OffsetPosition; + m_log.DebugFormat( + "[UNDO STATE]: Storing undo position {0} for child part", Position); -// m_log.DebugFormat( -// "[UNDO STATE]: Storing undo rotation {0} for child part", part.RotationOffset); Rotation = part.RotationOffset; + m_log.DebugFormat( + "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation); -// m_log.DebugFormat( -// "[UNDO STATE]: Storing undo scale {0} for child part", part.Shape.Scale); Scale = part.Shape.Scale; + m_log.DebugFormat( + "[UNDO STATE]: Storing undo scale {0} for child part", Scale); } } } -- cgit v1.1 From 1fdb16f1cdf6e2722a763cdc0e9b7af9fed27a29 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 05:05:50 +0100 Subject: Fix undo for rotation of the root prim in a linkset on its own. The only obviously broken things right now are the undo of the position of just a root prim (stays in place) and the fact that resizes need two undoes. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 17 +++++++++++------ OpenSim/Region/Framework/Scenes/UndoState.cs | 6 ++++-- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9076d73..d653e66 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3013,11 +3013,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - private void UpdateRootRotation(Quaternion rot) + public void UpdateRootRotation(Quaternion rot) { -// m_log.DebugFormat( -// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", -// Name, LocalId, rot); + m_log.DebugFormat( + "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", + Name, LocalId, rot); Quaternion axRot = rot; Quaternion oldParentRot = m_rootPart.RotationOffset; @@ -3046,6 +3046,7 @@ namespace OpenSim.Region.Framework.Scenes newRot *= Quaternion.Inverse(axRot); prim.RotationOffset = newRot; prim.ScheduleTerseUpdate(); + prim.IgnoreUndoUpdate = false; } } @@ -3054,12 +3055,16 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart childpart = parts[i]; if (childpart != m_rootPart) { - childpart.IgnoreUndoUpdate = false; - childpart.StoreUndoState(); +// childpart.IgnoreUndoUpdate = false; +// childpart.StoreUndoState(); } } m_rootPart.ScheduleTerseUpdate(); + + m_log.DebugFormat( + "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", + Name, LocalId, rot); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 68d4cb4..dc509d9 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -150,8 +150,10 @@ namespace OpenSim.Region.Framework.Scenes "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", part.RotationOffset, Rotation, part.Name, part.LocalId); - part.UpdateRotation(Rotation); - //part.RotationOffset = Rotation; + if (ForGroup) + part.UpdateRotation(Rotation); + else + part.ParentGroup.UpdateRootRotation(Rotation); if (Scale != Vector3.Zero) { -- cgit v1.1 From 62325829ecab7d956416ff0450faa3f90f267e6c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 05:14:58 +0100 Subject: comment out all kinds of debugging guff --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 10 +++--- .../Region/Framework/Scenes/SceneObjectGroup.cs | 30 +++++++++--------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ++++---- OpenSim/Region/Framework/Scenes/UndoState.cs | 36 +++++++++++----------- 4 files changed, 44 insertions(+), 44 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 00115cc..a34ad62 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11224,8 +11224,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (multipleupdate.AgentData.SessionID != SessionId) return false; - m_log.DebugFormat( - "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length); +// m_log.DebugFormat( +// "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length); Scene tScene = (Scene)m_scene; @@ -11247,9 +11247,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - m_log.DebugFormat( - "[CLIENT]: Processing block {0} type {1} for {2} {3}", - i, block.Type, part.Name, part.LocalId); +// m_log.DebugFormat( +// "[CLIENT]: Processing block {0} type {1} for {2} {3}", +// i, block.Type, part.Name, part.LocalId); // // Do this once since fetch parts creates a new array. // SceneObjectPart[] parts = part.ParentGroup.Parts; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index d653e66..0eaed91 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3015,9 +3015,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateRootRotation(Quaternion rot) { - m_log.DebugFormat( - "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", - Name, LocalId, rot); +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", +// Name, LocalId, rot); Quaternion axRot = rot; Quaternion oldParentRot = m_rootPart.RotationOffset; @@ -3050,21 +3050,21 @@ namespace OpenSim.Region.Framework.Scenes } } - for (int i = 0; i < parts.Length; i++) - { - SceneObjectPart childpart = parts[i]; - if (childpart != m_rootPart) - { -// childpart.IgnoreUndoUpdate = false; -// childpart.StoreUndoState(); - } - } +// for (int i = 0; i < parts.Length; i++) +// { +// SceneObjectPart childpart = parts[i]; +// if (childpart != m_rootPart) +// { +//// childpart.IgnoreUndoUpdate = false; +//// childpart.StoreUndoState(); +// } +// } m_rootPart.ScheduleTerseUpdate(); - m_log.DebugFormat( - "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", - Name, LocalId, rot); +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", +// Name, LocalId, rot); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c3aca15..0357cf9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3705,9 +3705,9 @@ namespace OpenSim.Region.Framework.Scenes m_undo.Push(nUndo); - m_log.DebugFormat( - "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", - Name, LocalId, forGroup, m_undo.Count); +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", +// Name, LocalId, forGroup, m_undo.Count); } } } @@ -3740,9 +3740,9 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_undo) { - m_log.DebugFormat( - "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", - Name, LocalId, m_undo.Count); +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", +// Name, LocalId, m_undo.Count); if (m_undo.Count > 0) { diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index dc509d9..b013d68 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -64,32 +64,32 @@ namespace OpenSim.Region.Framework.Scenes else Position = part.OffsetPosition; - m_log.DebugFormat( - "[UNDO STATE]: Storing undo position {0} for root part", Position); +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo position {0} for root part", Position); Rotation = part.RotationOffset; - m_log.DebugFormat( - "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation); +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation); Scale = part.Shape.Scale; - m_log.DebugFormat( - "[UNDO STATE]: Storing undo scale {0} for root part", Scale); +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo scale {0} for root part", Scale); } else { Position = part.OffsetPosition; - m_log.DebugFormat( - "[UNDO STATE]: Storing undo position {0} for child part", Position); +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo position {0} for child part", Position); Rotation = part.RotationOffset; - m_log.DebugFormat( - "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation); +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation); Scale = part.Shape.Scale; - m_log.DebugFormat( - "[UNDO STATE]: Storing undo scale {0} for child part", Scale); +// m_log.DebugFormat( +// "[UNDO STATE]: Storing undo scale {0} for child part", Scale); } } } @@ -134,9 +134,9 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0) { - m_log.DebugFormat( - "[UNDO STATE]: Undoing position to {0} for root part {1} {2}", - Position, part.Name, part.LocalId); +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing position to {0} for root part {1} {2}", +// Position, part.Name, part.LocalId); if (Position != Vector3.Zero) { @@ -146,9 +146,9 @@ namespace OpenSim.Region.Framework.Scenes part.OffsetPosition = Position; } - m_log.DebugFormat( - "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", - part.RotationOffset, Rotation, part.Name, part.LocalId); +// m_log.DebugFormat( +// "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", +// part.RotationOffset, Rotation, part.Name, part.LocalId); if (ForGroup) part.UpdateRotation(Rotation); -- cgit v1.1 From 0ef29da9b2844e567928fe6fe5e13da3ee1a37ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 05:20:04 +0100 Subject: refactor: rename UpdatePrimPosition() to UpdatePrimGroupPosition() for consistency --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 4 ++-- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2c71c70..6e66632 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2716,7 +2716,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientPrimEvents(IClientAPI client) { - client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition; + client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; @@ -2845,7 +2845,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) { - client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimPosition; + client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d5e0bbb..65dc2c9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1352,12 +1352,12 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Update the position of the given part + /// Update the position of the given group. /// /// /// /// - public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) + public void UpdatePrimGroupPosition(uint localID, Vector3 pos, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0eaed91..26b35a3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2840,10 +2840,10 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Update just the root prim position in a linkset /// /// - private void UpdateRootPosition(Vector3 pos) + public void UpdateRootPosition(Vector3 pos) { // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos); -- cgit v1.1 From bc3679b67dc074a9ef1e0e6ffb07bca844eb93c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 05:46:17 +0100 Subject: Fix undo when changing just the root prim's position in a linkset. I think (ha ha) this largely fixes undo, except for the fact that rotation a set of prims with 'edit linked parts' selected doesn't quite work properly (though this works fine if the checkbox isn't selected). Also, the double undo bug for resize is still present. Redo might be incredibly buggy, haven't even looked at that yet. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 ++++++---- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- OpenSim/Region/Framework/Scenes/UndoState.cs | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 26b35a3..b6fb5a4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2825,6 +2825,7 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos); part.StoreUndoState(false); + part.IgnoreUndoUpdate = true; if (part.UUID == m_rootPart.UUID) { @@ -2836,6 +2837,7 @@ namespace OpenSim.Region.Framework.Scenes } HasGroupChanged = true; + part.IgnoreUndoUpdate = false; } } @@ -2848,9 +2850,9 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos); - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].StoreUndoState(); +// SceneObjectPart[] parts = m_parts.GetArray(); +// for (int i = 0; i < parts.Length; i++) +// parts[i].StoreUndoState(); Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); Vector3 oldPos = @@ -2863,7 +2865,7 @@ namespace OpenSim.Region.Framework.Scenes axDiff *= Quaternion.Inverse(partRotation); diff = axDiff; - parts = m_parts.GetArray(); + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart obPart = parts[i]; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0357cf9..9d7f87a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -788,7 +788,7 @@ namespace OpenSim.Region.Framework.Scenes get { return m_offsetPosition; } set { - StoreUndoState(); +// StoreUndoState(); m_offsetPosition = value; if (ParentGroup != null && !ParentGroup.IsDeleted) diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index b013d68..6bf89c5 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -59,10 +59,10 @@ namespace OpenSim.Region.Framework.Scenes { ForGroup = forGroup; - if (ForGroup) +// if (ForGroup) Position = part.ParentGroup.AbsolutePosition; - else - Position = part.OffsetPosition; +// else +// Position = part.OffsetPosition; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo position {0} for root part", Position); @@ -143,7 +143,7 @@ namespace OpenSim.Region.Framework.Scenes if (ForGroup) part.ParentGroup.AbsolutePosition = Position; else - part.OffsetPosition = Position; + part.ParentGroup.UpdateRootPosition(Position); } // m_log.DebugFormat( -- cgit v1.1 From 9dd5a2449575d671075c673e5e39ef3e1a108a76 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 05:51:19 +0100 Subject: rip out pointless null checks in UndoState where part can never be null --- OpenSim/Region/Framework/Scenes/UndoState.cs | 153 +++++++++++++-------------- 1 file changed, 72 insertions(+), 81 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 6bf89c5..f7bed5a 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -53,44 +53,41 @@ namespace OpenSim.Region.Framework.Scenes /// True if the undo is for an entire group public UndoState(SceneObjectPart part, bool forGroup) { - if (part != null) + if (part.ParentID == 0) { - if (part.ParentID == 0) - { - ForGroup = forGroup; + ForGroup = forGroup; // if (ForGroup) - Position = part.ParentGroup.AbsolutePosition; + Position = part.ParentGroup.AbsolutePosition; // else // Position = part.OffsetPosition; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo position {0} for root part", Position); - Rotation = part.RotationOffset; + Rotation = part.RotationOffset; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation); - Scale = part.Shape.Scale; + Scale = part.Shape.Scale; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo scale {0} for root part", Scale); - } - else - { - Position = part.OffsetPosition; + } + else + { + Position = part.OffsetPosition; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo position {0} for child part", Position); - Rotation = part.RotationOffset; + Rotation = part.RotationOffset; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation); - Scale = part.Shape.Scale; + Scale = part.Shape.Scale; // m_log.DebugFormat( // "[UNDO STATE]: Storing undo scale {0} for child part", Scale); - } } } @@ -128,120 +125,114 @@ namespace OpenSim.Region.Framework.Scenes public void PlaybackState(SceneObjectPart part) { - if (part != null) - { - part.Undoing = true; + part.Undoing = true; - if (part.ParentID == 0) - { + if (part.ParentID == 0) + { // m_log.DebugFormat( // "[UNDO STATE]: Undoing position to {0} for root part {1} {2}", // Position, part.Name, part.LocalId); - if (Position != Vector3.Zero) - { - if (ForGroup) - part.ParentGroup.AbsolutePosition = Position; - else - part.ParentGroup.UpdateRootPosition(Position); - } + if (Position != Vector3.Zero) + { + if (ForGroup) + part.ParentGroup.AbsolutePosition = Position; + else + part.ParentGroup.UpdateRootPosition(Position); + } // m_log.DebugFormat( // "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", // part.RotationOffset, Rotation, part.Name, part.LocalId); - if (ForGroup) - part.UpdateRotation(Rotation); - else - part.ParentGroup.UpdateRootRotation(Rotation); + if (ForGroup) + part.UpdateRotation(Rotation); + else + part.ParentGroup.UpdateRootRotation(Rotation); - if (Scale != Vector3.Zero) - { + if (Scale != Vector3.Zero) + { // m_log.DebugFormat( // "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}", // part.Shape.Scale, Scale, part.Name, part.LocalId); - if (ForGroup) - part.ParentGroup.GroupResize(Scale); - else - part.Resize(Scale); - } - - part.ParentGroup.ScheduleGroupForTerseUpdate(); + if (ForGroup) + part.ParentGroup.GroupResize(Scale); + else + part.Resize(Scale); } - else + + part.ParentGroup.ScheduleGroupForTerseUpdate(); + } + else + { + if (Position != Vector3.Zero) { - if (Position != Vector3.Zero) - { // m_log.DebugFormat( // "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}", // part.OffsetPosition, Position, part.Name, part.LocalId); - part.OffsetPosition = Position; - } + part.OffsetPosition = Position; + } // m_log.DebugFormat( // "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}", // part.RotationOffset, Rotation, part.Name, part.LocalId); - part.UpdateRotation(Rotation); + part.UpdateRotation(Rotation); - if (Scale != Vector3.Zero) - { + if (Scale != Vector3.Zero) + { // m_log.DebugFormat( // "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}", // part.Shape.Scale, Scale, part.Name, part.LocalId); - part.Resize(Scale); - } - - part.ScheduleTerseUpdate(); + part.Resize(Scale); } - part.Undoing = false; + part.ScheduleTerseUpdate(); } + + part.Undoing = false; } public void PlayfwdState(SceneObjectPart part) { - if (part != null) - { - part.Undoing = true; - - if (part.ParentID == 0) - { - if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; + part.Undoing = true; - if (Rotation != Quaternion.Identity) - part.UpdateRotation(Rotation); + if (part.ParentID == 0) + { + if (Position != Vector3.Zero) + part.ParentGroup.AbsolutePosition = Position; - if (Scale != Vector3.Zero) - { - if (ForGroup) - part.ParentGroup.GroupResize(Scale); - else - part.Resize(Scale); - } + if (Rotation != Quaternion.Identity) + part.UpdateRotation(Rotation); - part.ParentGroup.ScheduleGroupForTerseUpdate(); - } - else + if (Scale != Vector3.Zero) { - if (Position != Vector3.Zero) - part.OffsetPosition = Position; + if (ForGroup) + part.ParentGroup.GroupResize(Scale); + else + part.Resize(Scale); + } - if (Rotation != Quaternion.Identity) - part.UpdateRotation(Rotation); + part.ParentGroup.ScheduleGroupForTerseUpdate(); + } + else + { + if (Position != Vector3.Zero) + part.OffsetPosition = Position; - if (Scale != Vector3.Zero) - part.Resize(Scale); + if (Rotation != Quaternion.Identity) + part.UpdateRotation(Rotation); - part.ScheduleTerseUpdate(); - } + if (Scale != Vector3.Zero) + part.Resize(Scale); - part.Undoing = false; + part.ScheduleTerseUpdate(); } + + part.Undoing = false; } } -- cgit v1.1 From 25c532f2ec0c747eb9c9b6f8fff477a4fb375894 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 05:58:52 +0100 Subject: refator: simplify UndoState.Compare() code --- OpenSim/Region/Framework/Scenes/UndoState.cs | 29 +++++++++------------------- 1 file changed, 9 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index f7bed5a..393f42d 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -101,23 +101,15 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { if (part.ParentID == 0) - { - if (Position == part.ParentGroup.AbsolutePosition - && Rotation == part.RotationOffset - && Scale == part.Shape.Scale) - return true; - else - return false; - } + return + Position == part.ParentGroup.AbsolutePosition + && Rotation == part.RotationOffset + && Scale == part.Shape.Scale; else - { - if (Position == part.OffsetPosition - && Rotation == part.RotationOffset - && Scale == part.Shape.Scale) - return true; - else - return false; - } + return + Position == part.OffsetPosition + && Rotation == part.RotationOffset + && Scale == part.Shape.Scale; } return false; @@ -249,10 +241,7 @@ namespace OpenSim.Region.Framework.Scenes public bool Compare(ITerrainChannel terrainChannel) { - if (m_terrainChannel != terrainChannel) - return false; - else - return false; + return m_terrainChannel == terrainChannel; } public void PlaybackState() -- cgit v1.1 From ec1ecd363317fd83fd30f45d9c033873f4c35bc2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 06:05:23 +0100 Subject: stop redo throwing an exception if there is nothing to redo --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9d7f87a..ccf8a25 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3778,23 +3778,26 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", // Name, LocalId, m_redo.Count); - UndoState gofwd = m_redo.Pop(); - - if (gofwd != null) + if (m_redo.Count > 0) { - if (m_parentGroup.GetSceneMaxUndo() > 0) + UndoState gofwd = m_redo.Pop(); + + if (gofwd != null) { - UndoState nUndo = new UndoState(this, gofwd.ForGroup); - - m_undo.Push(nUndo); + if (m_parentGroup.GetSceneMaxUndo() > 0) + { + UndoState nUndo = new UndoState(this, gofwd.ForGroup); + + m_undo.Push(nUndo); + } + + gofwd.PlayfwdState(this); } - gofwd.PlayfwdState(this); - } - // m_log.DebugFormat( // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", // Name, LocalId, m_redo.Count); + } } } -- cgit v1.1 From c50533659a9c7627cd6b24820078192b18c662f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 06:11:16 +0100 Subject: If we store an undo, wipe anything already present on the redo stack This stops problems when we undo a few steps and start off down another path. Surprisingly, apart from this now fixed problem, redo appears to be working too. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ccf8a25..e8097fa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3705,6 +3705,9 @@ namespace OpenSim.Region.Framework.Scenes m_undo.Push(nUndo); + if (m_redo.Count > 0) + m_redo.Clear(); + // m_log.DebugFormat( // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", // Name, LocalId, forGroup, m_undo.Count); -- cgit v1.1 From ee829a71c2e42d4434d8cec2cfc1d048d50904f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jul 2011 06:13:05 +0100 Subject: On all undo/redo operations, consistently lock the undo object for everything, in order to avoid any deadlock issues. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e8097fa..f74f263 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3775,7 +3775,7 @@ namespace OpenSim.Region.Framework.Scenes public void Redo() { - lock (m_redo) + lock (m_undo) { // m_log.DebugFormat( // "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", @@ -3811,10 +3811,6 @@ namespace OpenSim.Region.Framework.Scenes lock (m_undo) { m_undo.Clear(); - } - - lock (m_redo) - { m_redo.Clear(); } } -- cgit v1.1 From 51c47677a15bd41eeab2f36ac71384984712362b Mon Sep 17 00:00:00 2001 From: Careminster Team Date: Tue, 19 Jul 2011 10:15:34 -0700 Subject: Tidy up a superfluous AddPrimShape override in PhysicsScene --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f74f263..4629757 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4533,7 +4533,6 @@ namespace OpenSim.Region.Framework.Scenes { // It's not phantom anymore. So make sure the physics engine get's knowledge of it PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( - LocalId, string.Format("{0}/{1}", Name, UUID), Shape, AbsolutePosition, -- cgit v1.1 From 9fc7d65df7a094649eaa34921827ed1316ab67a5 Mon Sep 17 00:00:00 2001 From: Careminster Team Date: Tue, 19 Jul 2011 10:25:49 -0700 Subject: Apply the localID to the Physics actor to prevent null calls later --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 6fda32d..a307469 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1677,7 +1677,7 @@ namespace OpenSim.Region.Physics.OdePlugin } private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, - IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) + IMesh mesh, PrimitiveBaseShape pbs, bool isphysical, uint localID) { Vector3 pos = position; Vector3 siz = size; @@ -1691,7 +1691,7 @@ namespace OpenSim.Region.Physics.OdePlugin lock (_prims) _prims.Add(newPrim); } - + newPrim.LocalID = localID; return newPrim; } @@ -1733,7 +1733,7 @@ namespace OpenSim.Region.Physics.OdePlugin // } // } - result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); + result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid); return result; } -- cgit v1.1 From 3270bd560e29fcc871cab6e99a504903eef7af0e Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 20 Jul 2011 14:34:02 -0700 Subject: Removed unused AddPrimShape methods in PhysicsScene caused by merge conflicts --- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 28ace34..3870411 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -88,23 +88,9 @@ namespace OpenSim.Region.Physics.Manager public abstract void RemovePrim(PhysicsActor prim); - //public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - // Vector3 size, Quaternion rotation); //To be removed - Actually removed! - public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid); - public virtual PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, uint localid) - { - PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid); - - if (ret != null) - ret.LocalID = localID; - - return ret; - } - public virtual float TimeDilation { get { return 1.0f; } -- cgit v1.1 From f97278610c2ab9717b32b9c64bc5865b0b47dd41 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 4 Jul 2011 17:54:14 +0300 Subject: Fixed updating avatar appearance Signed-off-by: root --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 75dbeb8..9037c80 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory changed = sp.Appearance.SetVisualParams(visualParams); if (sp.Appearance.AvatarHeight > 0) sp.SetHeight(sp.Appearance.AvatarHeight); - } + } // Process the baked texture array if (textureEntry != null) @@ -387,11 +387,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); // we need to clean out the existing textures - sp.Appearance.ResetAppearance(); + sp.Appearance.ResetAppearance(); - // operate on a copy of the appearance so we don't have to lock anything + // operate on a copy of the appearance so we don't have to lock anything yet AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); - + foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) { if (wear.Type < AvatarWearable.MAX_WEARABLES) @@ -403,12 +403,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, ref avatAppearance); - // could get fancier with the locks here, but in the spirit of "last write wins" - // this should work correctly, also, we don't need to send the appearance here - // since the "iswearing" will trigger a new set of visual param and baked texture changes - // when those complete, the new appearance will be sent - sp.Appearance = avatAppearance; - QueueAppearanceSave(client.AgentId); + lock (m_setAppearanceLock) + { + // Update only those fields that we have changed. This is important because the viewer + // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing + // shouldn't overwrite the changes made in SetAppearance. + sp.Appearance.Wearables = avatAppearance.Wearables; + sp.Appearance.Texture = avatAppearance.Texture; + + // We don't need to send the appearance here since the "iswearing" will trigger a new set + // of visual param and baked texture changes. When those complete, the new appearance will be sent + + QueueAppearanceSave(client.AgentId); + } } private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) -- cgit v1.1 From 56830bfe07234b0f4b48737a921cc6eae68d9a39 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 12 Jul 2011 12:56:34 +0300 Subject: When handling SetAppearance packet, always save the appearance; not only if the texture was changed --- .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 9037c80..995a552 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -224,12 +224,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // update transaction. In theory, we should be able to do an immediate // appearance send and save here. - // save only if there were changes, send no matter what (doesn't hurt to send twice) - if (changed) - QueueAppearanceSave(client.AgentId); - - QueueAppearanceSend(client.AgentId); } + // save only if there were changes, send no matter what (doesn't hurt to send twice) + if (changed) + QueueAppearanceSave(client.AgentId); + + QueueAppearanceSend(client.AgentId); } // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); -- cgit v1.1 From 02e54c57c4901167779f07ed3e89fb1d24ffc22a Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Fri, 22 Jul 2011 11:33:00 +0300 Subject: Generate the initial maptile asynchronously Signed-off-by: Melanie --- .../CoreModules/World/WorldMap/WorldMapModule.cs | 10 ++++++---- OpenSim/Region/Framework/Scenes/Scene.cs | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 6e142bb..fac2dab 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -1110,14 +1110,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (data == null) return; - UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID; - m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); - m_scene.RegionInfo.RegionSettings.TerrainImageID = UUID.Random(); + UUID terrainImageID = UUID.Random(); AssetBase asset = new AssetBase( - m_scene.RegionInfo.RegionSettings.TerrainImageID, + terrainImageID, "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(), (sbyte)AssetType.Texture, m_scene.RegionInfo.RegionID.ToString()); @@ -1129,6 +1127,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // Store the new one m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); m_scene.AssetService.Store(asset); + + // Switch to the new one + UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID; + m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID; m_scene.RegionInfo.RegionSettings.Save(); // Delete the old one diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6e66632..32a2887 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1672,20 +1672,20 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService.SetScene(this); - // If we generate maptiles internally at all, the maptile generator - // will register the region. If not, do it here - if (m_generateMaptiles) + GridRegion region = new GridRegion(RegionInfo); + string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); + if (error != String.Empty) { - RegenerateMaptile(null, null); + throw new Exception(error); } - else + + // Generate the maptile asynchronously, because sometimes it can be very slow and we + // don't want this to delay starting the region. + if (m_generateMaptiles) { - GridRegion region = new GridRegion(RegionInfo); - string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); - if (error != String.Empty) - { - throw new Exception(error); - } + Util.FireAndForget(delegate { + RegenerateMaptile(null, null); + }); } } -- cgit v1.1 From 5ffec1cd648bc8dcc333fc528707c09bb8dce27d Mon Sep 17 00:00:00 2001 From: Robert.Adams Date: Fri, 22 Jul 2011 10:22:21 -0700 Subject: Pass collisions and updates in pinned memory (saves marshaling). Fix folding feet by using collision normals. Add constraint specification. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 5 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 140 +++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 86 +++++++------ .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 18 ++- 4 files changed, 151 insertions(+), 98 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d9e236f..dbd7285 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -185,7 +185,7 @@ public class BSCharacter : PhysicsActor get { return _force; } set { _force = value; - m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); + // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); _scene.TaintedObject(delegate() { BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); @@ -411,8 +411,9 @@ public class BSCharacter : PhysicsActor _collidingGroundStep = _scene.SimulationStep; } + // throttle collisions to the rate specified in the subscription if (_subscribedEventsMs == 0) return; // don't want collisions - int nowTime = Util.EnvironmentTickCount(); + int nowTime = _scene.SimulationNowTime; if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; _lastCollisionTime = nowTime; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 82a8803..f2ab2d9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -261,6 +261,7 @@ public sealed class BSPrim : PhysicsActor { if (_childrenPrims.Contains(child)) { + BulletSimAPI.RemoveConstraint(_scene.WorldID, child.LocalID, this.LocalID); _childrenPrims.Remove(child); child.ParentPrim = null; // the child has lost its parent RecreateGeomAndObject(); // rebuild my shape with the child removed @@ -1018,47 +1019,8 @@ public sealed class BSPrim : PhysicsActor if (IsRootOfLinkset) { // Create a linkset around this object - /* - * NOTE: the original way of creating a linkset was to create a compound hull in the - * root which consisted of the hulls of all the children. This didn't work well because - * OpenSimulator needs updates and collisions for all the children and the physics - * engine didn't create events for the children when the root hull was moved. - * This code creates the compound hull. - // If I am the root prim of a linkset, replace my physical shape with all the - // pieces of the children. - // All of the children should have called CreateGeom so they have a hull - // in the physics engine already. Here we pull together all of those hulls - // into one shape. - int totalPrimsInLinkset = _childrenPrims.Count + 1; - // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset); - ShapeData[] shapes = new ShapeData[totalPrimsInLinkset]; - FillShapeInfo(out shapes[0]); - int ii = 1; - foreach (BSPrim prim in _childrenPrims) - { - // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID); - prim.FillShapeInfo(out shapes[ii]); - ii++; - } - BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes); - */ - // Create the linkset by putting constraints between the objects of the set so they cannot move - // relative to each other. - // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); - - // remove any constraints that might be in place - foreach (BSPrim prim in _childrenPrims) - { - BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID); - } - // create constraints between the root prim and each of the children - foreach (BSPrim prim in _childrenPrims) - { - // this is a constraint that allows no freedom of movement between the two objects - // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 - BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, OMV.Vector3.Zero, OMV.Vector3.Zero, - OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero); - } + CreateLinksetWithCompoundHull(); + // CreateLinksetWithConstraints(); } else { @@ -1070,6 +1032,73 @@ public sealed class BSPrim : PhysicsActor } } + // Create a linkset by creating a compound hull at the root prim that consists of all + // the children. + void CreateLinksetWithCompoundHull() + { + // If I am the root prim of a linkset, replace my physical shape with all the + // pieces of the children. + // All of the children should have called CreateGeom so they have a hull + // in the physics engine already. Here we pull together all of those hulls + // into one shape. + int totalPrimsInLinkset = _childrenPrims.Count + 1; + // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset); + ShapeData[] shapes = new ShapeData[totalPrimsInLinkset]; + FillShapeInfo(out shapes[0]); + int ii = 1; + foreach (BSPrim prim in _childrenPrims) + { + // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID); + prim.FillShapeInfo(out shapes[ii]); + ii++; + } + BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes); + } + + // Create the linkset by putting constraints between the objects of the set so they cannot move + // relative to each other. + void CreateLinksetWithConstraints() + { + // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); + + // remove any constraints that might be in place + foreach (BSPrim prim in _childrenPrims) + { + // m_log.DebugFormat("{0}: CreateObject: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); + BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID); + } + // create constraints between the root prim and each of the children + foreach (BSPrim prim in _childrenPrims) + { + // this is a constraint that allows no freedom of movement between the two objects + // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 + // m_log.DebugFormat("{0}: CreateObject: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); + + // relative position normalized to the root prim + OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation); + // OMV.Quaternion relativeRotation = OMV.Quaternion.Identity; + + // rotation is pointing up the vector between the object centers + OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromAxisAngle(childRelativePosition, 0f); + + /* // the logic for relative rotation from http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6391 + OMV.Vector3 rrn = childRelativePosition; + rrn.Normalize(); + rrn /= rrn.X; + OMV.Matrix4 rotmat = new OMV.Matrix4(rrn.X, rrn.Y, rrn.Z, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromRotationMatrix(rotmat); + */ + + BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, + childRelativePosition / 2, + relativeRotation, + -childRelativePosition / 2, + relativeRotation, + OMV.Vector3.Zero, OMV.Vector3.Zero, + OMV.Vector3.Zero, OMV.Vector3.Zero); + } + } + // Copy prim's info into the BulletSim shape description structure public void FillShapeInfo(out ShapeData shape) { @@ -1118,50 +1147,53 @@ public sealed class BSPrim : PhysicsActor // The physics engine says that properties have updated. Update same and inform // the world that things have changed. // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() - private int UpPropPosition = 1 << 0; - private int UpPropRotation = 1 << 1; - private int UpPropVelocity = 1 << 2; - private int UpPropAcceleration = 1 << 3; - private int UpPropAngularVel = 1 << 4; + enum UpdatedProperties { + Position = 1 << 0, + Rotation = 1 << 1, + Velocity = 1 << 2, + Acceleration = 1 << 3, + AngularVel = 1 << 4 + } public void UpdateProperties(EntityProperties entprop) { - int changed = 0; + UpdatedProperties changed = 0; // assign to the local variables so the normal set action does not happen if (_position != entprop.Position) { _position = entprop.Position; // m_log.DebugFormat("{0}: UpdateProperties: position = {1}", LogHeader, _position); - changed |= UpPropPosition; + changed |= UpdatedProperties.Position; } if (_orientation != entprop.Rotation) { _orientation = entprop.Rotation; // m_log.DebugFormat("{0}: UpdateProperties: rotation = {1}", LogHeader, _orientation); - changed |= UpPropRotation; + changed |= UpdatedProperties.Rotation; } if (_velocity != entprop.Velocity) { _velocity = entprop.Velocity; // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity); - changed |= UpPropVelocity; + changed |= UpdatedProperties.Velocity; } if (_acceleration != entprop.Acceleration) { _acceleration = entprop.Acceleration; // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration); - changed |= UpPropAcceleration; + changed |= UpdatedProperties.Acceleration; } if (_rotationalVelocity != entprop.AngularVelocity) { _rotationalVelocity = entprop.AngularVelocity; // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); - changed |= UpPropAngularVel; + changed |= UpdatedProperties.AngularVel; } if (changed != 0) { // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); - base.RequestPhysicsterseUpdate(); + if (this._parentPrim == null) + base.RequestPhysicsterseUpdate(); } } @@ -1178,7 +1210,7 @@ public sealed class BSPrim : PhysicsActor if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events // throttle the collisions to the number of milliseconds specified in the subscription - int nowTime = Util.EnvironmentTickCount(); + int nowTime = _scene.SimulationNowTime; if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; _lastCollisionTime = nowTime; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index beffd21..062945f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -38,9 +38,7 @@ using OpenSim.Region.Framework; // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) // Fix folding up feet -// Fix terrain. Only flat terrain works. Terrain with shape is oriented wrong? Origined wrong? // Parameterize BulletSim. Pass a structure of parameters to the C++ code. Capsule size, friction, ... -// Shift drag duplication of objects does not work // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) // Test sculpties // Compute physics FPS reasonably @@ -82,6 +80,19 @@ public class BSScene : PhysicsScene private long m_simulationStep = 0; public long SimulationStep { get { return m_simulationStep; } } + // A value of the time now so all the collision and update routines do not have to get their own + // Set to 'now' just before all the prims and actors are called for collisions and updates + private int m_simulationNowTime; + public int SimulationNowTime { get { return m_simulationNowTime; } } + + private int m_maxCollisionsPerFrame = 2048; + private CollisionDesc[] m_collisionArray; + private GCHandle m_collisionArrayPinnedHandle; + + private int m_maxUpdatesPerFrame = 2048; + private EntityProperties[] m_updateArray; + private GCHandle m_updateArrayPinnedHandle; + private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes public float maximumMassObject = 10000.01f; @@ -129,8 +140,19 @@ public class BSScene : PhysicsScene _taintedObjects = new List(); mesher = meshmerizer; + // The bounding box for the simulated world + Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f); + + // Allocate pinned memory to pass back object property updates and collisions from simulation step + m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; + m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); + m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; + m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - m_worldID = BulletSimAPI.Initialize(new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f)); + m_worldID = BulletSimAPI.Initialize(worldExtent, + m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), + m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); } // Called directly from unmanaged code so don't do much @@ -188,19 +210,7 @@ public class BSScene : PhysicsScene } public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation) // deprecated - { - return null; - } - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) - { - m_log.ErrorFormat("{0}: CALL TO AddPrimShape in BSScene. NOT IMPLEMENTED", LogHeader); - return null; - } - - public override PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical) + Vector3 size, Quaternion rotation, bool isPhysical, uint localID) { // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); IMesh mesh = null; @@ -225,10 +235,8 @@ public class BSScene : PhysicsScene { int updatedEntityCount; IntPtr updatedEntitiesPtr; - IntPtr[] updatedEntities; int collidersCount; IntPtr collidersPtr; - int[] colliders; // should be uint but Marshal.Copy does not have that overload // update the prim states while we know the physics engine is not busy ProcessTaints(); @@ -242,32 +250,33 @@ public class BSScene : PhysicsScene int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); - // if there were collisions, they show up here + // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in + + // Get a value for 'now' so all the collision and update routines don't have to get their own + m_simulationNowTime = Util.EnvironmentTickCount(); + + // If there were collisions, process them by sending the event to the prim. + // Collisions must be processed before updates. if (collidersCount > 0) { - colliders = new int[collidersCount]; - Marshal.Copy(collidersPtr, colliders, 0, collidersCount); - for (int ii = 0; ii < collidersCount; ii+=2) + for (int ii = 0; ii < collidersCount; ii++) { - uint cA = (uint)colliders[ii]; - uint cB = (uint)colliders[ii+1]; - SendCollision(cA, cB); - SendCollision(cB, cA); + uint cA = m_collisionArray[ii].aID; + uint cB = m_collisionArray[ii].bID; + Vector3 point = m_collisionArray[ii].point; + Vector3 normal = m_collisionArray[ii].normal; + SendCollision(cA, cB, point, normal, 0.01f); + SendCollision(cB, cA, point, -normal, 0.01f); } } - // if any of the objects had updated properties, they are returned in the updatedEntity structure - // TODO: figure out how to pass all of the EntityProperties structures in one marshal call. + // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) { - updatedEntities = new IntPtr[updatedEntityCount]; - // fetch all the pointers to all the EntityProperties structures for these updates - Marshal.Copy(updatedEntitiesPtr, updatedEntities, 0, updatedEntityCount); for (int ii = 0; ii < updatedEntityCount; ii++) { - IntPtr updatePointer = updatedEntities[ii]; - EntityProperties entprop = (EntityProperties)Marshal.PtrToStructure(updatePointer, typeof(EntityProperties)); - // m_log.DebugFormat("{0}: entprop: id={1}, pos={2}", LogHeader, entprop.ID, entprop.Position); + EntityProperties entprop = m_updateArray[ii]; + // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); BSCharacter actor; if (m_avatars.TryGetValue(entprop.ID, out actor)) { @@ -282,12 +291,12 @@ public class BSScene : PhysicsScene } } - // fps calculation wrong. This calculation returns about 1 in normal operation. + // fps calculation wrong. This calculation always returns about 1 in normal operation. return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; } // Something has collided - private void SendCollision(uint localID, uint collidingWith) + private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration) { if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) { @@ -303,12 +312,12 @@ public class BSScene : PhysicsScene BSPrim prim; if (m_prims.TryGetValue(localID, out prim)) { - prim.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f); + prim.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f); return; } BSCharacter actor; if (m_avatars.TryGetValue(localID, out actor)) { - actor.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f); + actor.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f); return; } return; @@ -317,7 +326,6 @@ public class BSScene : PhysicsScene public override void GetResults() { } public override void SetTerrain(float[] heightMap) { - m_log.DebugFormat("{0}: SetTerrain", LogHeader); m_heightMap = heightMap; this.TaintedObject(delegate() { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index b2bc0d7..ace8158 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -78,7 +78,13 @@ public struct RaycastHit public float Fraction; public Vector3 Normal; } - +public struct CollisionDesc +{ + public uint aID; + public uint bID; + public Vector3 point; + public Vector3 normal; +} public struct EntityProperties { public uint ID; @@ -92,7 +98,8 @@ public struct EntityProperties static class BulletSimAPI { [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern uint Initialize(Vector3 maxPosition); +public static extern uint Initialize(Vector3 maxPosition, int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); @@ -124,7 +131,12 @@ public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void AddConstraint(uint worldID, uint id1, uint id2, - Vector3 frame1, Vector3 frame2, Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); + Vector3 frame1, Quaternion frame1rot, + Vector3 frame2, Quaternion frame2rot, + Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool RemoveConstraintByID(uint worldID, uint id1); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); -- cgit v1.1 From aadc4eb3b8d1c4a30cee7b69efac9197a974f45b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jul 2011 19:23:38 +0100 Subject: Fix problem where sculpts were not getting physical proxies Fixed this by inspecting Shape.SculptEntry at various places instead of Shape.SculptType. Sculpties actually have a SculptType of Cylinder - only true mesh is SculptType.Mesh This addresses http://opensimulator.org/mantis/view.php?id=5595 --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4629757..5791b95 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1038,7 +1038,7 @@ namespace OpenSim.Region.Framework.Scenes { actor.Size = m_shape.Scale; - if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + if (Shape.SculptEntry) CheckSculptAndLoad(); else ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); @@ -1906,7 +1906,7 @@ namespace OpenSim.Region.Framework.Scenes // If this part is a sculpt then delay the physics update until we've asynchronously loaded the // mesh data. - if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + if (Shape.SculptEntry) CheckSculptAndLoad(); else m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); -- cgit v1.1 From 869883f2dc51f2b2210ccf8fd41f3de0c07e39fc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 22 Jul 2011 15:23:57 -0700 Subject: BulletSim: fix buoyancy for prims. Start of configurable physics parameters. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 12 ++- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 97 ++++++++++++++++++---- 2 files changed, 92 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index dbd7285..82361ad 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -107,7 +107,7 @@ public class BSCharacter : PhysicsActor shapeData.Velocity = _velocity; shapeData.Scale = _scale; shapeData.Mass = _mass; - shapeData.Buoyancy = isFlying ? 0f : 1f; + shapeData.Buoyancy = isFlying ? 1f : 0f; shapeData.Static = ShapeData.numericFalse; // do actual create at taint time @@ -258,7 +258,7 @@ public class BSCharacter : PhysicsActor _scene.TaintedObject(delegate() { // simulate flying by changing the effect of gravity - BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 0f : 1f); + BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 1f : 0f); }); } } @@ -296,7 +296,13 @@ public class BSCharacter : PhysicsActor } public override float Buoyancy { get { return _buoyancy; } - set { _buoyancy = value; } + set { _buoyancy = value; + _scene.TaintedObject(delegate() + { + // simulate flying by changing the effect of gravity + BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); + }); + } } // Used for MoveTo diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 062945f..7c11f2b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -37,7 +37,6 @@ using OpenMetaverse; using OpenSim.Region.Framework; // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Fix folding up feet // Parameterize BulletSim. Pass a structure of parameters to the C++ code. Capsule size, friction, ... // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) // Test sculpties @@ -108,6 +107,31 @@ public class BSScene : PhysicsScene private List _taintedObjects; private Object _taintLock = new Object(); + // A pointer to an instance if this structure is passed to the C++ code + // Format of this structure must match the definition in the C++ code + private struct ConfigurationParameters + { + public float defaultFriction; + public float defaultDensity; + public float collisionMargin; + public float gravity; + + public float linearDamping; + public float angularDamping; + public float deactivationTime; + public float linearSleepingThreshold; + public float angularSleepingThreshold; + + public float terrainFriction; + public float terrainHitFriction; + public float terrainRestitution; + public float avatarFriction; + public float avatarCapsuleRadius; + public float avatarCapsuleHeight; + } + ConfigurationParameters m_params; + GCHandle m_paramsHandle; + private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; public BSScene(string identifier) @@ -116,16 +140,12 @@ public class BSScene : PhysicsScene public override void Initialise(IMesher meshmerizer, IConfigSource config) { - if (config != null) - { - IConfig pConfig = config.Configs["BulletSim"]; - if (pConfig != null) - { - DefaultFriction = pConfig.GetFloat("Friction", DefaultFriction); - DefaultDensity = pConfig.GetFloat("Density", DefaultDensity); - // TODO: a lot more parameters that are passed to BulletSim - } - } + m_params = new ConfigurationParameters(); + m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned); + + // Set default values for physics parameters plus any overrides from the ini file + GetInitialParameterValues(config); + // if Debug, enable logging from the unmanaged code if (m_log.IsDebugEnabled) { @@ -134,9 +154,6 @@ public class BSScene : PhysicsScene BulletSimAPI.SetDebugLogCallback(debugLogCallbackHandle); } - _meshSculptedPrim = true; // mesh sculpted prims - _forceSimplePrimMeshing = false; // use complex meshing if called for - _taintedObjects = new List(); mesher = meshmerizer; @@ -155,6 +172,58 @@ public class BSScene : PhysicsScene m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); } + private void GetInitialParameterValues(IConfigSource config) + { + _meshSculptedPrim = true; // mesh sculpted prims + _forceSimplePrimMeshing = false; // use complex meshing if called for + + // Set the default values for the physics parameters + m_params.defaultFriction = 0.70f; + m_params.defaultDensity = 10.000006836f; // Aluminum g/cm3 + m_params.collisionMargin = 0.0f; + m_params.gravity = -9.80665f; + + m_params.linearDamping = 0.1f; + m_params.angularDamping = 0.85f; + m_params.deactivationTime = 0.2f; + m_params.linearSleepingThreshold = 0.8f; + m_params.angularSleepingThreshold = 1.0f; + + m_params.terrainFriction = 0.85f; + m_params.terrainHitFriction = 0.8f; + m_params.terrainRestitution = 0.2f; + m_params.avatarFriction = 0.85f; + m_params.avatarCapsuleRadius = 0.37f; + m_params.avatarCapsuleHeight = 1.5f; // 2.140599f + + if (config != null) + { + // If there are specifications in the ini file, use those values + IConfig pConfig = config.Configs["BulletSim"]; + if (pConfig != null) + { + _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", true); + _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", false); + + m_params.defaultFriction = pConfig.GetFloat("DefaultFriction", m_params.defaultFriction); + m_params.defaultDensity = pConfig.GetFloat("DefaultDensity", m_params.defaultDensity); + m_params.collisionMargin = pConfig.GetFloat("CollisionMargin", m_params.collisionMargin); + m_params.gravity = pConfig.GetFloat("Gravity", m_params.gravity); + m_params.linearDamping = pConfig.GetFloat("LinearDamping", m_params.linearDamping); + m_params.angularDamping = pConfig.GetFloat("AngularDamping", m_params.angularDamping); + m_params.deactivationTime = pConfig.GetFloat("DeactivationTime", m_params.deactivationTime); + m_params.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", m_params.linearSleepingThreshold); + m_params.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", m_params.angularSleepingThreshold); + m_params.terrainFriction = pConfig.GetFloat("TerrainFriction", m_params.terrainFriction); + m_params.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", m_params.terrainHitFriction); + m_params.terrainRestitution = pConfig.GetFloat("TerrainRestitution", m_params.terrainRestitution); + m_params.avatarFriction = pConfig.GetFloat("AvatarFriction", m_params.avatarFriction); + m_params.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", m_params.avatarCapsuleRadius); + m_params.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", m_params.avatarCapsuleHeight); + } + } + } + // Called directly from unmanaged code so don't do much private void BulletLogger(string msg) { -- cgit v1.1 From 667b54f5a2a04fa5a2859397868d270eab3913f1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Jul 2011 01:59:14 +0100 Subject: Don't load current/next/everyone/base permissions from the library item xml files - always use PermissionMask.All instead (which was the existing default). Library items always need the same permissions, so it doesn't make sense to load them from the xml files. This just opens the door to permissions mistakes. --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 4 ++++ OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 8 +++++++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 5 ++++- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index b714f2b..4933147 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -984,11 +984,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) { InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); + if (assetRequestItem == null) { ILibraryService lib = m_Scene.RequestModuleInterface(); + if (lib != null) assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); + if (assetRequestItem == null) return false; } @@ -1019,6 +1022,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.WarnFormat( "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); + return false; } diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index d570608..2ef4457 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -185,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); archread.Execute(); } + foreach (InventoryNodeBase node in nodes) FixPerms(node); } @@ -197,18 +198,23 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread.Close(); } } - } private void FixPerms(InventoryNodeBase node) { + m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID); + if (node is InventoryItemBase) { InventoryItemBase item = (InventoryItemBase)node; +// item.BasePermissions = (uint)PermissionMask.All; item.BasePermissions = 0x7FFFFFFF; item.EveryOnePermissions = 0x7FFFFFFF; item.CurrentPermissions = 0x7FFFFFFF; item.NextPermissions = 0x7FFFFFFF; +// item.EveryOnePermissions = (uint)PermissionMask.Copy; +// item.CurrentPermissions = (uint)PermissionMask.None; +// item.NextPermissions = (uint)PermissionMask.All; } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 30421d4..afc1a4f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -724,7 +724,10 @@ namespace OpenSim.Region.Framework.Scenes newName = item.Name; } - if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) + if (remoteClient.AgentId == oldAgentID + || (LibraryService != null + && LibraryService.LibraryRootFolder != null + && oldAgentID == LibraryService.LibraryRootFolder.Owner)) { CreateNewInventoryItem( remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, -- cgit v1.1 From fcaa4f601231a6feb7fd5ea40e35fba6220c6235 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Jul 2011 02:05:51 +0100 Subject: Revert "Don't load current/next/everyone/base permissions from the library item xml files - always use PermissionMask.All instead (which was the existing default)." There actually are uses for this. I will correct the perms instead since some entries appear to be wrong. This reverts commit 667b54f5a2a04fa5a2859397868d270eab3913f1. --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 4 ---- OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 8 +------- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 5 +---- 3 files changed, 2 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 4933147..b714f2b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -984,14 +984,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) { InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); - if (assetRequestItem == null) { ILibraryService lib = m_Scene.RequestModuleInterface(); - if (lib != null) assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); - if (assetRequestItem == null) return false; } @@ -1022,7 +1019,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.WarnFormat( "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); - return false; } diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index 2ef4457..d570608 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -185,7 +185,6 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); archread.Execute(); } - foreach (InventoryNodeBase node in nodes) FixPerms(node); } @@ -198,23 +197,18 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread.Close(); } } + } private void FixPerms(InventoryNodeBase node) { - m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID); - if (node is InventoryItemBase) { InventoryItemBase item = (InventoryItemBase)node; -// item.BasePermissions = (uint)PermissionMask.All; item.BasePermissions = 0x7FFFFFFF; item.EveryOnePermissions = 0x7FFFFFFF; item.CurrentPermissions = 0x7FFFFFFF; item.NextPermissions = 0x7FFFFFFF; -// item.EveryOnePermissions = (uint)PermissionMask.Copy; -// item.CurrentPermissions = (uint)PermissionMask.None; -// item.NextPermissions = (uint)PermissionMask.All; } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index afc1a4f..30421d4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -724,10 +724,7 @@ namespace OpenSim.Region.Framework.Scenes newName = item.Name; } - if (remoteClient.AgentId == oldAgentID - || (LibraryService != null - && LibraryService.LibraryRootFolder != null - && oldAgentID == LibraryService.LibraryRootFolder.Owner)) + if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) { CreateNewInventoryItem( remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, -- cgit v1.1 From f0895028e96e39ca179cad8c103042397ad870e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Jul 2011 02:13:11 +0100 Subject: Remove manually permissions settings on all current library items so that they use the defaults instead. Some items had completely wrong permissions - this is easier than correcting them all. The ability to set permissions in xml is retained since there are use cases for this (e.g. to create no-mod library scripts) --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 4 ++++ OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 8 +++++++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 5 ++++- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index b714f2b..4933147 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -984,11 +984,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) { InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); + if (assetRequestItem == null) { ILibraryService lib = m_Scene.RequestModuleInterface(); + if (lib != null) assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); + if (assetRequestItem == null) return false; } @@ -1019,6 +1022,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.WarnFormat( "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); + return false; } diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index d570608..2ef4457 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -185,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); archread.Execute(); } + foreach (InventoryNodeBase node in nodes) FixPerms(node); } @@ -197,18 +198,23 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread.Close(); } } - } private void FixPerms(InventoryNodeBase node) { + m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID); + if (node is InventoryItemBase) { InventoryItemBase item = (InventoryItemBase)node; +// item.BasePermissions = (uint)PermissionMask.All; item.BasePermissions = 0x7FFFFFFF; item.EveryOnePermissions = 0x7FFFFFFF; item.CurrentPermissions = 0x7FFFFFFF; item.NextPermissions = 0x7FFFFFFF; +// item.EveryOnePermissions = (uint)PermissionMask.Copy; +// item.CurrentPermissions = (uint)PermissionMask.None; +// item.NextPermissions = (uint)PermissionMask.All; } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 30421d4..afc1a4f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -724,7 +724,10 @@ namespace OpenSim.Region.Framework.Scenes newName = item.Name; } - if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) + if (remoteClient.AgentId == oldAgentID + || (LibraryService != null + && LibraryService.LibraryRootFolder != null + && oldAgentID == LibraryService.LibraryRootFolder.Owner)) { CreateNewInventoryItem( remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, -- cgit v1.1 From be9b4ad23abcb2dec2291679c758f0dc0bc6096e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Jul 2011 02:18:23 +0100 Subject: For default everyone permissions on library items, make notecards and scripts non-modifiable (but still copyable, etc). Users should not be given the impression that they can modify these items. This still does not solve the issue where library items cannot be dragged into prims or user inventory any time after they are initially seen. Curiously, manually copying and pasting still appears to work. On the surface, this seems to have something to do with library item caching on the client, since deleting the cache allows drag to work again once Not sure what the exact problem is. --- .../Region/CoreModules/Framework/Library/LibraryModule.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index 2ef4457..3155ce7 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -207,14 +207,10 @@ namespace OpenSim.Region.CoreModules.Framework.Library if (node is InventoryItemBase) { InventoryItemBase item = (InventoryItemBase)node; -// item.BasePermissions = (uint)PermissionMask.All; - item.BasePermissions = 0x7FFFFFFF; - item.EveryOnePermissions = 0x7FFFFFFF; - item.CurrentPermissions = 0x7FFFFFFF; - item.NextPermissions = 0x7FFFFFFF; -// item.EveryOnePermissions = (uint)PermissionMask.Copy; -// item.CurrentPermissions = (uint)PermissionMask.None; -// item.NextPermissions = (uint)PermissionMask.All; + item.BasePermissions = (uint)PermissionMask.All; + item.EveryOnePermissions = (uint)PermissionMask.All - (uint)PermissionMask.Modify; + item.CurrentPermissions = (uint)PermissionMask.All; + item.NextPermissions = (uint)PermissionMask.All; } } -- cgit v1.1 From 4eaca4884eca26ca4cb73a6ce4c7edee38b789ac Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Sun, 17 Jul 2011 11:22:29 +0900 Subject: Fixed serverside_object_permission default value confliction --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index a40517c..7cb3751 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); if (m_bypassPermissions) - m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); + m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks"); else m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); -- cgit v1.1 From 504de8bc4792eda165d71a2c7481cb43cb92759a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Jul 2011 03:46:55 +0100 Subject: Pass the first name and last name from the agent circuit data to the authorization service rather than from the account. This is to accomodate situations where the authorization service is being used by the hypergrid, where visitors have no user account. See http://opensimulator.org/mantis/view.php?id=5517, this code is somewhat adapted/cleaned up from Michelle's patch I'm a little ambivalent about this since visitors could put anything in firstname/lastname so it's not much of an auth measure. It's up to the auth service to decide which data it actually uses. Possibly we should be passing through other info such as agent circuit ip --- .../LocalAuthorizationServiceConnector.cs | 17 ++++++++------- .../RemoteAuthorizationServiceConnector.cs | 24 ++++++++++++++-------- OpenSim/Region/Framework/Scenes/Scene.cs | 5 +++-- 3 files changed, 27 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs index 85a1ac3..18a7177 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs @@ -39,8 +39,7 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization { - public class LocalAuthorizationServicesConnector : - ISharedRegionModule, IAuthorizationService + public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService { private static readonly ILog m_log = LogManager.GetLogger( @@ -127,15 +126,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization if (!m_Enabled) return; - m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", scene.RegionInfo.RegionName); - - + m_log.InfoFormat( + "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", + scene.RegionInfo.RegionName); } - public bool IsAuthorizedForRegion(string userID, string regionID, out string message) + public bool IsAuthorizedForRegion( + string userID, string firstName, string lastName, string regionID, out string message) { - return m_AuthorizationService.IsAuthorizedForRegion(userID, regionID, out message); + return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message); } - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs index 66994fa..5fa27b8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs @@ -117,12 +117,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization } - public bool IsAuthorizedForRegion(string userID, string regionID, out string message) + public bool IsAuthorizedForRegion( + string userID, string firstName, string lastName, string regionID, out string message) { - m_log.InfoFormat("[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); + m_log.InfoFormat( + "[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); bool isAuthorized = true; message = String.Empty; + string mail = String.Empty; // get the scene this call is being made for Scene scene = null; @@ -140,17 +143,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization if (scene != null) { UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); - isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, - account.Email, scene.RegionInfo.RegionName, regionID, out message); + + if (account != null) + mail = account.Email; + + isAuthorized + = IsAuthorizedForRegion( + userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message); } else { - m_log.ErrorFormat("[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0} ",regionID); + m_log.ErrorFormat( + "[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0}", + regionID); } - return isAuthorized; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 32a2887..1a32510 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3553,11 +3553,12 @@ namespace OpenSim.Region.Framework.Scenes if (AuthorizationService != null) { - if (!AuthorizationService.IsAuthorizedForRegion(agent.AgentID.ToString(), RegionInfo.RegionID.ToString(),out reason)) + if (!AuthorizationService.IsAuthorizedForRegion( + agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); - //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName); + return false; } } -- cgit v1.1 From 4cdc8806fbc0d0d9b0ff878b30a4491b347cf2dc Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 23 Jul 2011 11:39:32 +0100 Subject: Fix LLTextBox to work with the updated libOMV --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 7 ++++++- OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs | 4 +++- OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 2 +- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a34ad62..60f0075 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12083,7 +12083,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task); } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); dialog.Data.ObjectID = objectId; @@ -12099,6 +12099,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP buttons[0] = new ScriptDialogPacket.ButtonsBlock(); buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!"); dialog.Buttons = buttons; + + dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1]; + dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock(); + dialog.OwnerData[0].OwnerID = ownerID; + OutPacket(dialog, ThrottleOutPacketType.Task); } diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index 0db31eb..36fe040 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -141,10 +141,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); string ownerFirstName, ownerLastName; + UUID ownerID = UUID.Zero; if (account != null) { ownerFirstName = account.FirstName; ownerLastName = account.LastName; + ownerID = account.PrincipalID; } else { @@ -155,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog ScenePresence sp = m_scene.GetScenePresence(avatarid); if (sp != null) - sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); + sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerID, ownerFirstName, ownerLastName, objectid); } public void SendNotificationToUsersInRegion( diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 56b46d7..17766ea 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -1152,7 +1152,7 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 88db20e..3335f2e 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1678,7 +1678,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 15bc1b7..3afcc8d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -1157,7 +1157,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } -- cgit v1.1 From c4ffcd4b7d978ad3a675da0f8ae3f97f027beae8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 27 Jul 2011 08:35:19 +0200 Subject: Ensure that packet headers get parsed correctly --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index aff90c5..f2388cd 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -160,6 +160,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public Socket Server { get { return null; } } + private int m_malformedCount = 0; // Guard against a spamming attack + public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) : base(listenIP, (int)port) { @@ -612,6 +614,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Decoding + if (buffer.DataLength < 7) + return; // Drop undersizd packet + + int headerLen = 7; + if (buffer.Data[6] == 0xFF) + { + if (buffer.Data[7] == 0xFF) + headerLen = 10; + else + headerLen = 8; + } + + if (buffer.DataLength < headerLen) + return; // Malformed header + try { packet = Packet.BuildPacket(buffer.Data, ref packetEnd, @@ -621,6 +638,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP catch (MalformedDataException) { } + catch (IndexOutOfRangeException) + { + return; // Drop short packet + } + catch(Exception e) + { + if (m_malformedCount < 100) + m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); + m_malformedCount++; + if ((m_malformedCount % 100000) == 0) + m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); + } // Fail-safe check if (packet == null) -- cgit v1.1 From 8c3eb324c4b666e7abadef4a714d1bd8d5f71ac2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 00:00:35 +0100 Subject: When using osTeleportAgent() and osTeleportAvatar(), only teleport if the region name exactly matches (not near matches) This is to prevent situations where the first name returned by GridService.GetRegionsByName is not one that exactly matches the given region name, even when there is an exact match later on in the list. Only the above two functions call this teleport method (the map uses a different routine) so this seems safe to change. Addresses http://opensimulator.org/mantis/view.php?id=5606 --- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1a32510..b84c3d5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3881,8 +3881,11 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Tries to teleport agent to other region. + /// Tries to teleport agent to another region. /// + /// + /// The region name must exactly match that given. + /// /// /// /// @@ -3891,15 +3894,16 @@ namespace OpenSim.Region.Framework.Scenes public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, Vector3 lookat, uint teleportFlags) { - List regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1); - if (regions == null || regions.Count == 0) + GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); + + if (region == null) { // can't find the region: Tell viewer and abort remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); return; } - RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags); + RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags); } /// -- cgit v1.1 From 9c6227da661952ddc808e6c5fb0da5ebf774f0cb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 00:23:42 +0100 Subject: refactor: unindent the OdeScene.Simulate() loop to ignore the long commented out ifs and locks This is to make it more readable. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 544 ++++++++++++++------------- 1 file changed, 274 insertions(+), 270 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index a307469..a6d737e 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2687,320 +2687,321 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); //if (!ode.lockquery()) //{ // ode.dlock(world); - try - { - // Insert, remove Characters - bool processedtaints = false; - lock (_taintedActors) - { - if (_taintedActors.Count > 0) - { - foreach (OdeCharacter character in _taintedActors) - { - character.ProcessTaints(timeStep); + try + { + // Insert, remove Characters + bool processedtaints = false; - processedtaints = true; - //character.m_collisionscore = 0; - } + lock (_taintedActors) + { + if (_taintedActors.Count > 0) + { + foreach (OdeCharacter character in _taintedActors) + { + character.ProcessTaints(timeStep); - if (processedtaints) - _taintedActors.Clear(); - } + processedtaints = true; + //character.m_collisionscore = 0; } - // Modify other objects in the scene. - processedtaints = false; + if (processedtaints) + _taintedActors.Clear(); + } + } + + // Modify other objects in the scene. + processedtaints = false; - lock (_taintedPrimLock) + lock (_taintedPrimLock) + { + foreach (OdePrim prim in _taintedPrimL) + { + if (prim.m_taintremove) { - foreach (OdePrim prim in _taintedPrimL) - { - if (prim.m_taintremove) - { - //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); - RemovePrimThreadLocked(prim); - } - else - { - //Console.WriteLine("Simulate calls ProcessTaints"); - prim.ProcessTaints(timeStep); - } - processedtaints = true; - prim.m_collisionscore = 0; - - // This loop can block up the Heartbeat for a very long time on large regions. - // We need to let the Watchdog know that the Heartbeat is not dead - // NOTE: This is currently commented out, but if things like OAR loading are - // timing the heartbeat out we will need to uncomment it - //Watchdog.UpdateThread(); - } + //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); + RemovePrimThreadLocked(prim); + } + else + { + //Console.WriteLine("Simulate calls ProcessTaints"); + prim.ProcessTaints(timeStep); + } + processedtaints = true; + prim.m_collisionscore = 0; + + // This loop can block up the Heartbeat for a very long time on large regions. + // We need to let the Watchdog know that the Heartbeat is not dead + // NOTE: This is currently commented out, but if things like OAR loading are + // timing the heartbeat out we will need to uncomment it + //Watchdog.UpdateThread(); + } - if (SupportsNINJAJoints) - { - // Create pending joints, if possible + if (SupportsNINJAJoints) + { + // Create pending joints, if possible - // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating - // a joint requires specifying the body id of both involved bodies - if (pendingJoints.Count > 0) + // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating + // a joint requires specifying the body id of both involved bodies + if (pendingJoints.Count > 0) + { + List successfullyProcessedPendingJoints = new List(); + //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); + foreach (PhysicsJoint joint in pendingJoints) + { + //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); + string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + List jointBodies = new List(); + bool allJointBodiesAreReady = true; + foreach (string jointParam in jointParams) { - List successfullyProcessedPendingJoints = new List(); - //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); - foreach (PhysicsJoint joint in pendingJoints) + if (jointParam == "NULL") { - //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); - string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); - List jointBodies = new List(); - bool allJointBodiesAreReady = true; - foreach (string jointParam in jointParams) + //DoJointErrorMessage(joint, "attaching NULL joint to world"); + jointBodies.Add(IntPtr.Zero); + } + else + { + //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); + bool foundPrim = false; + lock (_prims) { - if (jointParam == "NULL") - { - //DoJointErrorMessage(joint, "attaching NULL joint to world"); - jointBodies.Add(IntPtr.Zero); - } - else + foreach (OdePrim prim in _prims) // FIXME: inefficient { - //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); - bool foundPrim = false; - lock (_prims) + if (prim.SOPName == jointParam) { - foreach (OdePrim prim in _prims) // FIXME: inefficient + //DoJointErrorMessage(joint, "found for prim name: " + jointParam); + if (prim.IsPhysical && prim.Body != IntPtr.Zero) { - if (prim.SOPName == jointParam) - { - //DoJointErrorMessage(joint, "found for prim name: " + jointParam); - if (prim.IsPhysical && prim.Body != IntPtr.Zero) - { - jointBodies.Add(prim.Body); - foundPrim = true; - break; - } - else - { - DoJointErrorMessage(joint, "prim name " + jointParam + - " exists but is not (yet) physical; deferring joint creation. " + - "IsPhysical property is " + prim.IsPhysical + - " and body is " + prim.Body); - foundPrim = false; - break; - } - } + jointBodies.Add(prim.Body); + foundPrim = true; + break; + } + else + { + DoJointErrorMessage(joint, "prim name " + jointParam + + " exists but is not (yet) physical; deferring joint creation. " + + "IsPhysical property is " + prim.IsPhysical + + " and body is " + prim.Body); + foundPrim = false; + break; } - } - if (foundPrim) - { - // all is fine - } - else - { - allJointBodiesAreReady = false; - break; } } } - if (allJointBodiesAreReady) + if (foundPrim) { - //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); - if (jointBodies[0] == jointBodies[1]) - { - DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); - } - else - { - switch (joint.Type) - { - case PhysicsJointType.Ball: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating ball joint "); - odeJoint = d.JointCreateBall(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetBallAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - //DoJointErrorMessage(joint, "ODE joint setting OK"); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); - //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); - //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); - - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - case PhysicsJointType.Hinge: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating hinge joint "); - odeJoint = d.JointCreateHinge(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetHingeAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - // We use the orientation of the x-axis of the joint's coordinate frame - // as the axis for the hinge. - - // Therefore, we must get the joint's coordinate frame based on the - // joint.Rotation field, which originates from the orientation of the - // joint's proxy object in the scene. - - // The joint's coordinate frame is defined as the transformation matrix - // that converts a vector from joint-local coordinates into world coordinates. - // World coordinates are defined as the XYZ coordinate system of the sim, - // as shown in the top status-bar of the viewer. - - // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) - // and use that as the hinge axis. - - //joint.Rotation.Normalize(); - Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); - - // Now extract the X axis of the joint's coordinate frame. - - // Do not try to use proxyFrame.AtAxis or you will become mired in the - // tar pit of transposed, inverted, and generally messed-up orientations. - // (In other words, Matrix4.AtAxis() is borked.) - // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness - - // Instead, compute the X axis of the coordinate frame by transforming - // the (1,0,0) vector. At least that works. - - //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); - Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); - //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); - //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); - d.JointSetHingeAxis(odeJoint, - jointAxis.X, - jointAxis.Y, - jointAxis.Z); - //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - } - successfullyProcessedPendingJoints.Add(joint); - } + // all is fine } else { - DoJointErrorMessage(joint, "joint could not yet be created; still pending"); + allJointBodiesAreReady = false; + break; } } - foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) + } + if (allJointBodiesAreReady) + { + //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); + if (jointBodies[0] == jointBodies[1]) { - //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); - //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); - InternalRemovePendingJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); - InternalAddActiveJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "done"); + DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); + } + else + { + switch (joint.Type) + { + case PhysicsJointType.Ball: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating ball joint "); + odeJoint = d.JointCreateBall(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetBallAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + //DoJointErrorMessage(joint, "ODE joint setting OK"); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); + //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); + //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); + + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + case PhysicsJointType.Hinge: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating hinge joint "); + odeJoint = d.JointCreateHinge(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetHingeAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + // We use the orientation of the x-axis of the joint's coordinate frame + // as the axis for the hinge. + + // Therefore, we must get the joint's coordinate frame based on the + // joint.Rotation field, which originates from the orientation of the + // joint's proxy object in the scene. + + // The joint's coordinate frame is defined as the transformation matrix + // that converts a vector from joint-local coordinates into world coordinates. + // World coordinates are defined as the XYZ coordinate system of the sim, + // as shown in the top status-bar of the viewer. + + // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) + // and use that as the hinge axis. + + //joint.Rotation.Normalize(); + Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); + + // Now extract the X axis of the joint's coordinate frame. + + // Do not try to use proxyFrame.AtAxis or you will become mired in the + // tar pit of transposed, inverted, and generally messed-up orientations. + // (In other words, Matrix4.AtAxis() is borked.) + // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness + + // Instead, compute the X axis of the coordinate frame by transforming + // the (1,0,0) vector. At least that works. + + //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); + Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); + //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); + //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); + d.JointSetHingeAxis(odeJoint, + jointAxis.X, + jointAxis.Y, + jointAxis.Z); + //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + } + successfullyProcessedPendingJoints.Add(joint); } } - } - - if (processedtaints) -//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); - _taintedPrimH.Clear(); - _taintedPrimL.Clear(); - } - - // Move characters - lock (_characters) - { - List defects = new List(); - foreach (OdeCharacter actor in _characters) - { - if (actor != null) - actor.Move(timeStep, defects); - } - if (0 != defects.Count) - { - foreach (OdeCharacter defect in defects) + else { - RemoveCharacter(defect); + DoJointErrorMessage(joint, "joint could not yet be created; still pending"); } } - } - - // Move other active objects - lock (_activeprims) - { - foreach (OdePrim prim in _activeprims) + foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) { - prim.m_collisionscore = 0; - prim.Move(timeStep); + //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); + //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); + InternalRemovePendingJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); + InternalAddActiveJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "done"); } } + } - //if ((framecount % m_randomizeWater) == 0) - // randomizeWater(waterlevel); + if (processedtaints) +//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); + _taintedPrimH.Clear(); + _taintedPrimL.Clear(); + } - //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); - m_rayCastManager.ProcessQueuedRequests(); + // Move characters + lock (_characters) + { + List defects = new List(); + foreach (OdeCharacter actor in _characters) + { + if (actor != null) + actor.Move(timeStep, defects); + } + if (0 != defects.Count) + { + foreach (OdeCharacter defect in defects) + { + RemoveCharacter(defect); + } + } + } - collision_optimized(timeStep); + // Move other active objects + lock (_activeprims) + { + foreach (OdePrim prim in _activeprims) + { + prim.m_collisionscore = 0; + prim.Move(timeStep); + } + } - lock (_collisionEventPrim) - { - foreach (PhysicsActor obj in _collisionEventPrim) - { - if (obj == null) - continue; + //if ((framecount % m_randomizeWater) == 0) + // randomizeWater(waterlevel); - switch ((ActorTypes)obj.PhysicsActorType) - { - case ActorTypes.Agent: - OdeCharacter cobj = (OdeCharacter)obj; - cobj.AddCollisionFrameTime(100); - cobj.SendCollisions(); - break; - case ActorTypes.Prim: - OdePrim pobj = (OdePrim)obj; - pobj.SendCollisions(); - break; - } - } - } + //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); + m_rayCastManager.ProcessQueuedRequests(); - //if (m_global_contactcount > 5) - //{ - // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); - //} + collision_optimized(timeStep); - m_global_contactcount = 0; - - d.WorldQuickStep(world, ODE_STEPSIZE); - d.JointGroupEmpty(contactgroup); - //ode.dunlock(world); - } - catch (Exception e) + lock (_collisionEventPrim) + { + foreach (PhysicsActor obj in _collisionEventPrim) { - m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); - ode.dunlock(world); + if (obj == null) + continue; + + switch ((ActorTypes)obj.PhysicsActorType) + { + case ActorTypes.Agent: + OdeCharacter cobj = (OdeCharacter)obj; + cobj.AddCollisionFrameTime(100); + cobj.SendCollisions(); + break; + case ActorTypes.Prim: + OdePrim pobj = (OdePrim)obj; + pobj.SendCollisions(); + break; + } } + } - step_time -= ODE_STEPSIZE; - i++; + //if (m_global_contactcount > 5) + //{ + // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); + //} + + m_global_contactcount = 0; + + d.WorldQuickStep(world, ODE_STEPSIZE); + d.JointGroupEmpty(contactgroup); + //ode.dunlock(world); + } + catch (Exception e) + { + m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); + ode.dunlock(world); + } + + step_time -= ODE_STEPSIZE; + i++; //} //else //{ @@ -3091,8 +3092,10 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); fwriter.WriteLine(header); fwriter.Close(); } + d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } + latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics @@ -3694,6 +3697,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); //d.CloseODE(); } } + public override Dictionary GetTopColliders() { Dictionary returncolliders = new Dictionary(); -- cgit v1.1 From 3f0d8f3cbf0b340848aa938b83638567ba8b02cf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 00:39:02 +0100 Subject: refactor: Simplify reading OdeScene.Simulate() loop by shunting all the NINJA joints stuff into its own method. Now if ninja joints isn't active (which is the default) don't have to wade through a lot of massively indented irrelevant code. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 373 ++++++++++++++------------- 1 file changed, 191 insertions(+), 182 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index a6d737e..9d41b15 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2732,192 +2732,13 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); // This loop can block up the Heartbeat for a very long time on large regions. // We need to let the Watchdog know that the Heartbeat is not dead - // NOTE: This is currently commented out, but if things like OAR loading are + // NOTE: This is currently commented out, but if things like OAR loading are // timing the heartbeat out we will need to uncomment it //Watchdog.UpdateThread(); } if (SupportsNINJAJoints) - { - // Create pending joints, if possible - - // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating - // a joint requires specifying the body id of both involved bodies - if (pendingJoints.Count > 0) - { - List successfullyProcessedPendingJoints = new List(); - //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); - foreach (PhysicsJoint joint in pendingJoints) - { - //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); - string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); - List jointBodies = new List(); - bool allJointBodiesAreReady = true; - foreach (string jointParam in jointParams) - { - if (jointParam == "NULL") - { - //DoJointErrorMessage(joint, "attaching NULL joint to world"); - jointBodies.Add(IntPtr.Zero); - } - else - { - //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); - bool foundPrim = false; - lock (_prims) - { - foreach (OdePrim prim in _prims) // FIXME: inefficient - { - if (prim.SOPName == jointParam) - { - //DoJointErrorMessage(joint, "found for prim name: " + jointParam); - if (prim.IsPhysical && prim.Body != IntPtr.Zero) - { - jointBodies.Add(prim.Body); - foundPrim = true; - break; - } - else - { - DoJointErrorMessage(joint, "prim name " + jointParam + - " exists but is not (yet) physical; deferring joint creation. " + - "IsPhysical property is " + prim.IsPhysical + - " and body is " + prim.Body); - foundPrim = false; - break; - } - } - } - } - if (foundPrim) - { - // all is fine - } - else - { - allJointBodiesAreReady = false; - break; - } - } - } - if (allJointBodiesAreReady) - { - //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); - if (jointBodies[0] == jointBodies[1]) - { - DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); - } - else - { - switch (joint.Type) - { - case PhysicsJointType.Ball: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating ball joint "); - odeJoint = d.JointCreateBall(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetBallAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - //DoJointErrorMessage(joint, "ODE joint setting OK"); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); - //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); - //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); - - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - case PhysicsJointType.Hinge: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating hinge joint "); - odeJoint = d.JointCreateHinge(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetHingeAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - // We use the orientation of the x-axis of the joint's coordinate frame - // as the axis for the hinge. - - // Therefore, we must get the joint's coordinate frame based on the - // joint.Rotation field, which originates from the orientation of the - // joint's proxy object in the scene. - - // The joint's coordinate frame is defined as the transformation matrix - // that converts a vector from joint-local coordinates into world coordinates. - // World coordinates are defined as the XYZ coordinate system of the sim, - // as shown in the top status-bar of the viewer. - - // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) - // and use that as the hinge axis. - - //joint.Rotation.Normalize(); - Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); - - // Now extract the X axis of the joint's coordinate frame. - - // Do not try to use proxyFrame.AtAxis or you will become mired in the - // tar pit of transposed, inverted, and generally messed-up orientations. - // (In other words, Matrix4.AtAxis() is borked.) - // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness - - // Instead, compute the X axis of the coordinate frame by transforming - // the (1,0,0) vector. At least that works. - - //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); - Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); - //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); - //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); - d.JointSetHingeAxis(odeJoint, - jointAxis.X, - jointAxis.Y, - jointAxis.Z); - //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - } - successfullyProcessedPendingJoints.Add(joint); - } - } - else - { - DoJointErrorMessage(joint, "joint could not yet be created; still pending"); - } - } - foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) - { - //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); - //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); - InternalRemovePendingJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); - InternalAddActiveJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "done"); - } - } - } + SimulateNINJAJoints(); if (processedtaints) //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); @@ -3095,7 +2916,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } - + latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics @@ -3117,6 +2938,194 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); return fps; } + /// + /// Simulate NINJA joints. + /// + /// + /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else. + /// + protected void SimulateNINJAJoints() + { + // Create pending joints, if possible + + // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating + // a joint requires specifying the body id of both involved bodies + if (pendingJoints.Count > 0) + { + List successfullyProcessedPendingJoints = new List(); + //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); + foreach (PhysicsJoint joint in pendingJoints) + { + //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); + string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + List jointBodies = new List(); + bool allJointBodiesAreReady = true; + foreach (string jointParam in jointParams) + { + if (jointParam == "NULL") + { + //DoJointErrorMessage(joint, "attaching NULL joint to world"); + jointBodies.Add(IntPtr.Zero); + } + else + { + //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); + bool foundPrim = false; + lock (_prims) + { + foreach (OdePrim prim in _prims) // FIXME: inefficient + { + if (prim.SOPName == jointParam) + { + //DoJointErrorMessage(joint, "found for prim name: " + jointParam); + if (prim.IsPhysical && prim.Body != IntPtr.Zero) + { + jointBodies.Add(prim.Body); + foundPrim = true; + break; + } + else + { + DoJointErrorMessage(joint, "prim name " + jointParam + + " exists but is not (yet) physical; deferring joint creation. " + + "IsPhysical property is " + prim.IsPhysical + + " and body is " + prim.Body); + foundPrim = false; + break; + } + } + } + } + if (foundPrim) + { + // all is fine + } + else + { + allJointBodiesAreReady = false; + break; + } + } + } + if (allJointBodiesAreReady) + { + //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); + if (jointBodies[0] == jointBodies[1]) + { + DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); + } + else + { + switch (joint.Type) + { + case PhysicsJointType.Ball: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating ball joint "); + odeJoint = d.JointCreateBall(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetBallAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + //DoJointErrorMessage(joint, "ODE joint setting OK"); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); + //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); + //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); + + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + case PhysicsJointType.Hinge: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating hinge joint "); + odeJoint = d.JointCreateHinge(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetHingeAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + // We use the orientation of the x-axis of the joint's coordinate frame + // as the axis for the hinge. + + // Therefore, we must get the joint's coordinate frame based on the + // joint.Rotation field, which originates from the orientation of the + // joint's proxy object in the scene. + + // The joint's coordinate frame is defined as the transformation matrix + // that converts a vector from joint-local coordinates into world coordinates. + // World coordinates are defined as the XYZ coordinate system of the sim, + // as shown in the top status-bar of the viewer. + + // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) + // and use that as the hinge axis. + + //joint.Rotation.Normalize(); + Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); + + // Now extract the X axis of the joint's coordinate frame. + + // Do not try to use proxyFrame.AtAxis or you will become mired in the + // tar pit of transposed, inverted, and generally messed-up orientations. + // (In other words, Matrix4.AtAxis() is borked.) + // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness + + // Instead, compute the X axis of the coordinate frame by transforming + // the (1,0,0) vector. At least that works. + + //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); + Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); + //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); + //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); + d.JointSetHingeAxis(odeJoint, + jointAxis.X, + jointAxis.Y, + jointAxis.Z); + //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + } + successfullyProcessedPendingJoints.Add(joint); + } + } + else + { + DoJointErrorMessage(joint, "joint could not yet be created; still pending"); + } + } + foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) + { + //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); + //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); + InternalRemovePendingJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); + InternalAddActiveJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "done"); + } + } + } + public override void GetResults() { } -- cgit v1.1 From 2a39d0cdb01dfbcc8d8838a80380dabfd9e468e1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 00:51:07 +0100 Subject: refactor: Move another chunk of ninja code out of the OdeScene.Simulate() loop for consistency and readability. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 64 ++++++++++++++++------------ 1 file changed, 36 insertions(+), 28 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 9d41b15..c436fca 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2738,7 +2738,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } if (SupportsNINJAJoints) - SimulateNINJAJoints(); + SimulatePendingNINJAJoints(); if (processedtaints) //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); @@ -2839,6 +2839,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { if (actor.bad) m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); + actor.UpdatePositionAndVelocity(); } } @@ -2852,6 +2853,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { RemoveCharacter(chr); } + _badCharacter.Clear(); } } @@ -2867,30 +2869,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); actor.UpdatePositionAndVelocity(); if (SupportsNINJAJoints) - { - // If an actor moved, move its joint proxy objects as well. - // There seems to be an event PhysicsActor.OnPositionUpdate that could be used - // for this purpose but it is never called! So we just do the joint - // movement code here. - - if (actor.SOPName != null && - joints_connecting_actor.ContainsKey(actor.SOPName) && - joints_connecting_actor[actor.SOPName] != null && - joints_connecting_actor[actor.SOPName].Count > 0) - { - foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) - { - if (affectedJoint.IsInPhysicsEngine) - { - DoJointMoved(affectedJoint); - } - else - { - DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); - } - } - } - } + SimulateActorPendingJoints(actor); } } } @@ -2901,7 +2880,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); // Finished with all sim stepping. If requested, dump world state to file for debugging. // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? - if (physics_logging && (physics_logging_interval>0) && (framecount % physics_logging_interval == 0)) + if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0)) { string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file @@ -2925,7 +2904,9 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); // If Physics stalls, it takes longer which makes the tick count ms larger. if (latertickcount < 100) + { m_timeDilation = 1.0f; + } else { m_timeDilation = 100f / latertickcount; @@ -2939,12 +2920,12 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } /// - /// Simulate NINJA joints. + /// Simulate pending NINJA joints. /// /// /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else. /// - protected void SimulateNINJAJoints() + protected void SimulatePendingNINJAJoints() { // Create pending joints, if possible @@ -3007,6 +2988,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } } } + if (allJointBodiesAreReady) { //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); @@ -3126,6 +3108,32 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } } + protected void SimulateActorPendingJoints(OdePrim actor) + { + // If an actor moved, move its joint proxy objects as well. + // There seems to be an event PhysicsActor.OnPositionUpdate that could be used + // for this purpose but it is never called! So we just do the joint + // movement code here. + + if (actor.SOPName != null && + joints_connecting_actor.ContainsKey(actor.SOPName) && + joints_connecting_actor[actor.SOPName] != null && + joints_connecting_actor[actor.SOPName].Count > 0) + { + foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) + { + if (affectedJoint.IsInPhysicsEngine) + { + DoJointMoved(affectedJoint); + } + else + { + DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); + } + } + } + } + public override void GetResults() { } -- cgit v1.1 From f3c5a5b745eb134d3dbd63012df3e5f5e964e71c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 01:18:42 +0100 Subject: fix extremely minor Ode bug where the _taintedPrimL list would always be cleared on every OdeScene.Simulate() even if it was already empty. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index c436fca..cd2b156 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2719,14 +2719,15 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { if (prim.m_taintremove) { - //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); +// Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name); RemovePrimThreadLocked(prim); } else { - //Console.WriteLine("Simulate calls ProcessTaints"); +// Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name); prim.ProcessTaints(timeStep); } + processedtaints = true; prim.m_collisionscore = 0; @@ -2741,9 +2742,11 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); SimulatePendingNINJAJoints(); if (processedtaints) + { //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); _taintedPrimH.Clear(); _taintedPrimL.Clear(); + } } // Move characters @@ -2839,7 +2842,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { if (actor.bad) m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); - + actor.UpdatePositionAndVelocity(); } } @@ -3096,6 +3099,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); DoJointErrorMessage(joint, "joint could not yet be created; still pending"); } } + foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) { //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); @@ -3108,6 +3112,13 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } } + /// + /// Simulate the joint proxies of a NINJA actor. + /// + /// + /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there. + /// + /// protected void SimulateActorPendingJoints(OdePrim actor) { // If an actor moved, move its joint proxy objects as well. -- cgit v1.1 From 5043be13fb07a8e0a37c1f496e9bb6127b163dfd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 21:49:23 +0100 Subject: Return null from CreateMeshFromPrimMesher if OpenJPEG decoding of the sculpt data fails. This is to address http://opensimulator.org/mantis/view.php?id=5612 --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 5413aa8..8a9260c 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -456,11 +456,21 @@ namespace OpenSim.Region.Physics.Meshing { OpenMetaverse.Imaging.ManagedImage unusedData; OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); + + if (idata == null) + { + // In some cases it seems that the decode can return a null bitmap without throwing + // an exception + m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); + + return null; + } + unusedData = null; //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); - if (cacheSculptMaps && idata != null) + if (cacheSculptMaps) { try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } -- cgit v1.1 From 84c68c61bd4c3f20640b7af2376c40ad5c38dc2c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 22:27:04 +0100 Subject: When we start the appearance saving thread, make sure we set the culture to En_US so that a different culture doesn't save values with commas as decimal points, etc. This will hopefully stop giants stalking the grid. See http://opensimulator.org/mantis/view.php?id=5614 --- .../Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 995a552..20dff0c 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -305,6 +305,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private void HandleAppearanceSave(UUID agentid) { + // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved + // in a culture where decimal points are commas and then reloaded in a culture which just treats them as + // number seperators. + Culture.SetCurrentCulture(); + ScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { -- cgit v1.1 From 6d866ba6d5105365cc5dea901ee18824e90cdc4c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jul 2011 23:43:35 +0100 Subject: Temporarily put in a log line which shows which locale the user is running in. --- OpenSim/Region/Application/Application.cs | 4 ++++ OpenSim/Region/Application/OpenSim.cs | 2 ++ 2 files changed, 6 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 3b261e7..c130038 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -73,6 +73,7 @@ namespace OpenSim AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + // Add the arguments supplied when running the application to the configuration ArgvConfigSource configSource = new ArgvConfigSource(args); @@ -91,6 +92,9 @@ namespace OpenSim m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config"); } + m_log.DebugFormat( + "[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture); + // Increase the number of IOCP threads available. Mono defaults to a tragically low number int workerThreads, iocpThreads; System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 8add2af..259d753 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -130,7 +130,9 @@ namespace OpenSim //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString()); if (m_gui) // Driven by external GUI + { m_console = new CommandConsole("Region"); + } else { switch (m_consoleType) -- cgit v1.1 From c4c6b457c3bbedd292e210cdd4dbc416d1361fcb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 01:16:10 +0100 Subject: correct misleading "fcache status" text - deep scans are not performed when this command is invoked. --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 2b3f7f5..0b13dc5 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -765,7 +765,7 @@ namespace Flotsam.RegionModules.AssetCache foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) { - m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:"); + m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:"); string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); -- cgit v1.1 From 7791c1fd1eff983a0f9824e52c5f90f1657c77a8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 01:35:22 +0100 Subject: Replace the generic exception logging in flotsam asset cache with more specific stuff to return more information. --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 50 +++++++++++----------- 1 file changed, 24 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 0b13dc5..84fe506 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -301,7 +301,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}", + asset.ID, e.Message, e.StackTrace); } } @@ -361,7 +363,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (System.Runtime.Serialization.SerializationException e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", + filename, id, e.Message, e.StackTrace); // If there was a problem deserializing the asset, the asset may // either be corrupted OR was serialized under an old format @@ -371,7 +375,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", + filename, id, e.Message, e.StackTrace); } finally { @@ -380,7 +386,6 @@ namespace Flotsam.RegionModules.AssetCache } } - #if WAIT_ON_INPROGRESS_REQUESTS // Check if we're already downloading this asset. If so, try to wait for it to // download. @@ -403,7 +408,6 @@ namespace Flotsam.RegionModules.AssetCache m_RequestsForInprogress++; } #endif - return asset; } @@ -432,7 +436,6 @@ namespace Flotsam.RegionModules.AssetCache } m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); - } return asset; @@ -446,7 +449,7 @@ namespace Flotsam.RegionModules.AssetCache public void Expire(string id) { if (m_LogLevel >= 2) - m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id); + m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id); try { @@ -464,7 +467,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", + id, e.Message, e.StackTrace); } } @@ -602,7 +607,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to cache. Directory {1}, tempname {2}, filename {3}. Exception {4} {5}.", + asset.ID, directory, tempname, filename, e.Message, e.StackTrace); } finally { @@ -632,15 +639,6 @@ namespace Flotsam.RegionModules.AssetCache } } - private static void LogException(Exception e) - { - string[] text = e.ToString().Split(new char[] { '\n' }); - foreach (string t in text) - { - m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t); - } - } - /// /// Scan through the file cache, and return number of assets currently cached. /// @@ -693,8 +691,7 @@ namespace Flotsam.RegionModules.AssetCache s.ForEachSOG(delegate(SceneObjectGroup e) { gatherer.GatherAssetUuids(e, assets); - } - ); + }); } foreach (UUID assetID in assets.Keys) @@ -727,7 +724,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", + dir, m_CacheDirectory, e.Message, e.StackTrace); } } @@ -739,7 +738,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", + file, m_CacheDirectory, e.Message, e.StackTrace); } } } @@ -836,7 +837,6 @@ namespace Flotsam.RegionModules.AssetCache Util.FireAndForget(delegate { int assetsCached = CacheScenes(); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); - }); break; @@ -891,7 +891,6 @@ namespace Flotsam.RegionModules.AssetCache #region IAssetService Members - public AssetMetadata GetMetadata(string id) { AssetBase asset = Get(id); @@ -921,7 +920,6 @@ namespace Flotsam.RegionModules.AssetCache Cache(asset); return asset.ID; - } public bool UpdateContent(string id, byte[] data) @@ -940,4 +938,4 @@ namespace Flotsam.RegionModules.AssetCache #endregion } -} +} \ No newline at end of file -- cgit v1.1 From 122e01949df847d865d4ae5320ae926e5189c2ee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 02:08:32 +0100 Subject: refactor: move the code that generates physics meshs from prim mesh data into a separate method, in order to make the code more readable. --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 222 ++++++++++++++------------ 1 file changed, 123 insertions(+), 99 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 8a9260c..f97449c 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -301,131 +301,155 @@ namespace OpenSim.Region.Physics.Meshing } } - private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) + /// + /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim. + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimMeshData(string primName, PrimitiveBaseShape primShape, Vector3 size, List coords, List faces) { -// m_log.DebugFormat( -// "[MESH]: Creating physics proxy for {0}, shape {1}", -// primName, (OpenMetaverse.SculptType)primShape.SculptType); + m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); - PrimMesh primMesh; - PrimMesher.SculptMesh sculptMesh; - - List coords = new List(); - List faces = new List(); + OSD meshOsd = null; - Image idata = null; - string decodedSculptFileName = ""; + if (primShape.SculptData.Length <= 0) + { + m_log.Error("[MESH]: asset data is zero length"); + return false; + } - if (primShape.SculptEntry) + long start = 0; + using (MemoryStream data = new MemoryStream(primShape.SculptData)) { - if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) + try { - if (!useMeshiesPhysicsMesh) - return null; - - m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); - - OSD meshOsd = null; - - if (primShape.SculptData.Length <= 0) + OSD osd = OSDParser.DeserializeLLSDBinary(data); + if (osd is OSDMap) + meshOsd = (OSDMap)osd; + else { - m_log.Error("[MESH]: asset data is zero length"); - return null; + m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); + return false; } + } + catch (Exception e) + { + m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); + } - long start = 0; - using (MemoryStream data = new MemoryStream(primShape.SculptData)) - { - try - { - OSD osd = OSDParser.DeserializeLLSDBinary(data); - if (osd is OSDMap) - meshOsd = (OSDMap)osd; - else - { - m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); - return null; - } - } - catch (Exception e) - { - m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); - } - - start = data.Position; - } + start = data.Position; + } - if (meshOsd is OSDMap) - { - OSDMap physicsParms = null; - OSDMap map = (OSDMap)meshOsd; - if (map.ContainsKey("physics_shape")) - physicsParms = (OSDMap)map["physics_shape"]; // old asset format - else if (map.ContainsKey("physics_mesh")) - physicsParms = (OSDMap)map["physics_mesh"]; // new asset format - - if (physicsParms == null) - { - m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); - return null; - } + if (meshOsd is OSDMap) + { + OSDMap physicsParms = null; + OSDMap map = (OSDMap)meshOsd; + if (map.ContainsKey("physics_shape")) + physicsParms = (OSDMap)map["physics_shape"]; // old asset format + else if (map.ContainsKey("physics_mesh")) + physicsParms = (OSDMap)map["physics_mesh"]; // new asset format + + if (physicsParms == null) + { + m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); + return false; + } - int physOffset = physicsParms["offset"].AsInteger() + (int)start; - int physSize = physicsParms["size"].AsInteger(); + int physOffset = physicsParms["offset"].AsInteger() + (int)start; + int physSize = physicsParms["size"].AsInteger(); - if (physOffset < 0 || physSize == 0) - return null; // no mesh data in asset + if (physOffset < 0 || physSize == 0) + return false; // no mesh data in asset - OSD decodedMeshOsd = new OSD(); - byte[] meshBytes = new byte[physSize]; - System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); + OSD decodedMeshOsd = new OSD(); + byte[] meshBytes = new byte[physSize]; + System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); // byte[] decompressed = new byte[physSize * 5]; - try + try + { + using (MemoryStream inMs = new MemoryStream(meshBytes)) + { + using (MemoryStream outMs = new MemoryStream()) { - using (MemoryStream inMs = new MemoryStream(meshBytes)) + using (ZOutputStream zOut = new ZOutputStream(outMs)) { - using (MemoryStream outMs = new MemoryStream()) + byte[] readBuffer = new byte[2048]; + int readLen = 0; + while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) { - using (ZOutputStream zOut = new ZOutputStream(outMs)) - { - byte[] readBuffer = new byte[2048]; - int readLen = 0; - while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) - { - zOut.Write(readBuffer, 0, readLen); - } - zOut.Flush(); - outMs.Seek(0, SeekOrigin.Begin); - - byte[] decompressedBuf = outMs.GetBuffer(); - - decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); - } + zOut.Write(readBuffer, 0, readLen); } + zOut.Flush(); + outMs.Seek(0, SeekOrigin.Begin); + + byte[] decompressedBuf = outMs.GetBuffer(); + + decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); } } - catch (Exception e) - { - m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); - return null; - } + } + } + catch (Exception e) + { + m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); + return false; + } - OSDArray decodedMeshOsdArray = null; + OSDArray decodedMeshOsdArray = null; - // physics_shape is an array of OSDMaps, one for each submesh - if (decodedMeshOsd is OSDArray) - { + // physics_shape is an array of OSDMaps, one for each submesh + if (decodedMeshOsd is OSDArray) + { // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); - decodedMeshOsdArray = (OSDArray)decodedMeshOsd; - foreach (OSD subMeshOsd in decodedMeshOsdArray) - { - if (subMeshOsd is OSDMap) - AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); - } - } + decodedMeshOsdArray = (OSDArray)decodedMeshOsd; + foreach (OSD subMeshOsd in decodedMeshOsdArray) + { + if (subMeshOsd is OSDMap) + AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); } } + } + + return true; + } + + /// + /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type. + /// + /// + /// + /// + /// + /// + private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) + { +// m_log.DebugFormat( +// "[MESH]: Creating physics proxy for {0}, shape {1}", +// primName, (OpenMetaverse.SculptType)primShape.SculptType); + + PrimMesh primMesh; + PrimMesher.SculptMesh sculptMesh; + + List coords = new List(); + List faces = new List(); + + Image idata = null; + string decodedSculptFileName = ""; + + if (primShape.SculptEntry) + { + if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) + { + if (!useMeshiesPhysicsMesh) + return null; + + GeneratePointsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces); + } else { if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) -- cgit v1.1 From b0eacadeb44f8c2335caeeffcb0c391b793c6731 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 02:09:17 +0100 Subject: fix bug in previous commit --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index f97449c..b478a9c 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -448,7 +448,8 @@ namespace OpenSim.Region.Physics.Meshing if (!useMeshiesPhysicsMesh) return null; - GeneratePointsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces); + if (!GeneratePointsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces)) + return null; } else { -- cgit v1.1 From 4197f66052dbbe121e1c31aac56330d1ae79833f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 02:22:05 +0100 Subject: refactor: extract code which generate points and faces from sculpt data into it's own method. fix build break. --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 460 ++++++++++++++------------ 1 file changed, 240 insertions(+), 220 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index b478a9c..9dfaaa2 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -302,123 +302,6 @@ namespace OpenSim.Region.Physics.Meshing } /// - /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim. - /// - /// - /// - /// - /// Coords are added to this list by the method. - /// Faces are added to this list by the method. - /// true if coords and faces were successfully generated, false if not - private bool GenerateCoordsAndFacesFromPrimMeshData(string primName, PrimitiveBaseShape primShape, Vector3 size, List coords, List faces) - { - m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); - - OSD meshOsd = null; - - if (primShape.SculptData.Length <= 0) - { - m_log.Error("[MESH]: asset data is zero length"); - return false; - } - - long start = 0; - using (MemoryStream data = new MemoryStream(primShape.SculptData)) - { - try - { - OSD osd = OSDParser.DeserializeLLSDBinary(data); - if (osd is OSDMap) - meshOsd = (OSDMap)osd; - else - { - m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); - return false; - } - } - catch (Exception e) - { - m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); - } - - start = data.Position; - } - - if (meshOsd is OSDMap) - { - OSDMap physicsParms = null; - OSDMap map = (OSDMap)meshOsd; - if (map.ContainsKey("physics_shape")) - physicsParms = (OSDMap)map["physics_shape"]; // old asset format - else if (map.ContainsKey("physics_mesh")) - physicsParms = (OSDMap)map["physics_mesh"]; // new asset format - - if (physicsParms == null) - { - m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); - return false; - } - - int physOffset = physicsParms["offset"].AsInteger() + (int)start; - int physSize = physicsParms["size"].AsInteger(); - - if (physOffset < 0 || physSize == 0) - return false; // no mesh data in asset - - OSD decodedMeshOsd = new OSD(); - byte[] meshBytes = new byte[physSize]; - System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); -// byte[] decompressed = new byte[physSize * 5]; - try - { - using (MemoryStream inMs = new MemoryStream(meshBytes)) - { - using (MemoryStream outMs = new MemoryStream()) - { - using (ZOutputStream zOut = new ZOutputStream(outMs)) - { - byte[] readBuffer = new byte[2048]; - int readLen = 0; - while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) - { - zOut.Write(readBuffer, 0, readLen); - } - zOut.Flush(); - outMs.Seek(0, SeekOrigin.Begin); - - byte[] decompressedBuf = outMs.GetBuffer(); - - decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); - } - } - } - } - catch (Exception e) - { - m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); - return false; - } - - OSDArray decodedMeshOsdArray = null; - - // physics_shape is an array of OSDMaps, one for each submesh - if (decodedMeshOsd is OSDArray) - { -// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); - - decodedMeshOsdArray = (OSDArray)decodedMeshOsd; - foreach (OSD subMeshOsd in decodedMeshOsdArray) - { - if (subMeshOsd is OSDMap) - AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); - } - } - } - - return true; - } - - /// /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type. /// /// @@ -433,14 +316,10 @@ namespace OpenSim.Region.Physics.Meshing // primName, (OpenMetaverse.SculptType)primShape.SculptType); PrimMesh primMesh; - PrimMesher.SculptMesh sculptMesh; List coords = new List(); List faces = new List(); - Image idata = null; - string decodedSculptFileName = ""; - if (primShape.SculptEntry) { if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) @@ -448,109 +327,13 @@ namespace OpenSim.Region.Physics.Meshing if (!useMeshiesPhysicsMesh) return null; - if (!GeneratePointsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces)) + if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces)) return null; } else { - if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) - { - decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); - try - { - if (File.Exists(decodedSculptFileName)) - { - idata = Image.FromFile(decodedSculptFileName); - } - } - catch (Exception e) - { - m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); - - } - //if (idata != null) - // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); - } - - if (idata == null) - { - if (primShape.SculptData == null || primShape.SculptData.Length == 0) - return null; - - try - { - OpenMetaverse.Imaging.ManagedImage unusedData; - OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); - - if (idata == null) - { - // In some cases it seems that the decode can return a null bitmap without throwing - // an exception - m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); - - return null; - } - - unusedData = null; - - //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); - - if (cacheSculptMaps) - { - try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } - catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } - } - } - catch (DllNotFoundException) - { - m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); - return null; - } - catch (IndexOutOfRangeException) - { - m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); - return null; - } - catch (Exception ex) - { - m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); - return null; - } - } - - PrimMesher.SculptMesh.SculptType sculptType; - switch ((OpenMetaverse.SculptType)primShape.SculptType) - { - case OpenMetaverse.SculptType.Cylinder: - sculptType = PrimMesher.SculptMesh.SculptType.cylinder; - break; - case OpenMetaverse.SculptType.Plane: - sculptType = PrimMesher.SculptMesh.SculptType.plane; - break; - case OpenMetaverse.SculptType.Torus: - sculptType = PrimMesher.SculptMesh.SculptType.torus; - break; - case OpenMetaverse.SculptType.Sphere: - sculptType = PrimMesher.SculptMesh.SculptType.sphere; - break; - default: - sculptType = PrimMesher.SculptMesh.SculptType.plane; - break; - } - - bool mirror = ((primShape.SculptType & 128) != 0); - bool invert = ((primShape.SculptType & 64) != 0); - - sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); - - idata.Dispose(); - - sculptMesh.DumpRaw(baseDir, primName, "primMesh"); - - sculptMesh.Scale(size.X, size.Y, size.Z); - - coords = sculptMesh.coords; - faces = sculptMesh.faces; + if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, coords, faces)) + return null; } } else @@ -691,6 +474,243 @@ namespace OpenSim.Region.Physics.Meshing return mesh; } + /// + /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim. + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimMeshData( + string primName, PrimitiveBaseShape primShape, Vector3 size, List coords, List faces) + { + m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); + + OSD meshOsd = null; + + if (primShape.SculptData.Length <= 0) + { + m_log.Error("[MESH]: asset data is zero length"); + return false; + } + + long start = 0; + using (MemoryStream data = new MemoryStream(primShape.SculptData)) + { + try + { + OSD osd = OSDParser.DeserializeLLSDBinary(data); + if (osd is OSDMap) + meshOsd = (OSDMap)osd; + else + { + m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); + return false; + } + } + catch (Exception e) + { + m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); + } + + start = data.Position; + } + + if (meshOsd is OSDMap) + { + OSDMap physicsParms = null; + OSDMap map = (OSDMap)meshOsd; + if (map.ContainsKey("physics_shape")) + physicsParms = (OSDMap)map["physics_shape"]; // old asset format + else if (map.ContainsKey("physics_mesh")) + physicsParms = (OSDMap)map["physics_mesh"]; // new asset format + + if (physicsParms == null) + { + m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); + return false; + } + + int physOffset = physicsParms["offset"].AsInteger() + (int)start; + int physSize = physicsParms["size"].AsInteger(); + + if (physOffset < 0 || physSize == 0) + return false; // no mesh data in asset + + OSD decodedMeshOsd = new OSD(); + byte[] meshBytes = new byte[physSize]; + System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); +// byte[] decompressed = new byte[physSize * 5]; + try + { + using (MemoryStream inMs = new MemoryStream(meshBytes)) + { + using (MemoryStream outMs = new MemoryStream()) + { + using (ZOutputStream zOut = new ZOutputStream(outMs)) + { + byte[] readBuffer = new byte[2048]; + int readLen = 0; + while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) + { + zOut.Write(readBuffer, 0, readLen); + } + zOut.Flush(); + outMs.Seek(0, SeekOrigin.Begin); + + byte[] decompressedBuf = outMs.GetBuffer(); + + decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); + } + } + } + } + catch (Exception e) + { + m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); + return false; + } + + OSDArray decodedMeshOsdArray = null; + + // physics_shape is an array of OSDMaps, one for each submesh + if (decodedMeshOsd is OSDArray) + { +// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); + + decodedMeshOsdArray = (OSDArray)decodedMeshOsd; + foreach (OSD subMeshOsd in decodedMeshOsdArray) + { + if (subMeshOsd is OSDMap) + AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); + } + } + } + + return true; + } + + /// + /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. + /// + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimSculptData( + string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, List coords, List faces) + { + PrimMesher.SculptMesh sculptMesh; + Image idata = null; + string decodedSculptFileName = ""; + + if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) + { + decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); + try + { + if (File.Exists(decodedSculptFileName)) + { + idata = Image.FromFile(decodedSculptFileName); + } + } + catch (Exception e) + { + m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); + + } + //if (idata != null) + // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); + } + + if (idata == null) + { + if (primShape.SculptData == null || primShape.SculptData.Length == 0) + return false; + + try + { + OpenMetaverse.Imaging.ManagedImage unusedData; + OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); + + if (idata == null) + { + // In some cases it seems that the decode can return a null bitmap without throwing + // an exception + m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); + + return false; + } + + unusedData = null; + + //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); + + if (cacheSculptMaps) + { + try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } + catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } + } + } + catch (DllNotFoundException) + { + m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); + return false; + } + catch (IndexOutOfRangeException) + { + m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); + return false; + } + catch (Exception ex) + { + m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); + return false; + } + } + + PrimMesher.SculptMesh.SculptType sculptType; + switch ((OpenMetaverse.SculptType)primShape.SculptType) + { + case OpenMetaverse.SculptType.Cylinder: + sculptType = PrimMesher.SculptMesh.SculptType.cylinder; + break; + case OpenMetaverse.SculptType.Plane: + sculptType = PrimMesher.SculptMesh.SculptType.plane; + break; + case OpenMetaverse.SculptType.Torus: + sculptType = PrimMesher.SculptMesh.SculptType.torus; + break; + case OpenMetaverse.SculptType.Sphere: + sculptType = PrimMesher.SculptMesh.SculptType.sphere; + break; + default: + sculptType = PrimMesher.SculptMesh.SculptType.plane; + break; + } + + bool mirror = ((primShape.SculptType & 128) != 0); + bool invert = ((primShape.SculptType & 64) != 0); + + sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); + + idata.Dispose(); + + sculptMesh.DumpRaw(baseDir, primName, "primMesh"); + + sculptMesh.Scale(size.X, size.Y, size.Z); + + coords = sculptMesh.coords; + faces = sculptMesh.faces; + + return true; + } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { return CreateMesh(primName, primShape, size, lod, false); -- cgit v1.1 From 310a6852201812f0c489f3806559dbbc3fd4b2d3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 02:34:50 +0100 Subject: refactor: extract method that generates a physics mesh from prim shape data --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 258 ++++++++++++++------------ 1 file changed, 141 insertions(+), 117 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 9dfaaa2..e81b982 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -315,10 +315,8 @@ namespace OpenSim.Region.Physics.Meshing // "[MESH]: Creating physics proxy for {0}, shape {1}", // primName, (OpenMetaverse.SculptType)primShape.SculptType); - PrimMesh primMesh; - - List coords = new List(); - List faces = new List(); + List coords; + List faces; if (primShape.SculptEntry) { @@ -327,126 +325,19 @@ namespace OpenSim.Region.Physics.Meshing if (!useMeshiesPhysicsMesh) return null; - if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces)) + if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces)) return null; } else { - if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, coords, faces)) + if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces)) return null; } } else { - float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; - float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; - float pathBegin = (float)primShape.PathBegin * 2.0e-5f; - float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; - float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; - float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; - - float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; - float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; - float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; - if (profileHollow > 0.95f) - profileHollow = 0.95f; - - int sides = 4; - if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) - sides = 3; - else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - sides = 24; - else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) - { // half circle, prim is a sphere - sides = 24; - - profileBegin = 0.5f * profileBegin + 0.5f; - profileEnd = 0.5f * profileEnd + 0.5f; - } - - int hollowSides = sides; - if (primShape.HollowShape == HollowShape.Circle) - hollowSides = 24; - else if (primShape.HollowShape == HollowShape.Square) - hollowSides = 4; - else if (primShape.HollowShape == HollowShape.Triangle) - hollowSides = 3; - - primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); - - if (primMesh.errorMessage != null) - if (primMesh.errorMessage.Length > 0) - m_log.Error("[ERROR] " + primMesh.errorMessage); - - primMesh.topShearX = pathShearX; - primMesh.topShearY = pathShearY; - primMesh.pathCutBegin = pathBegin; - primMesh.pathCutEnd = pathEnd; - - if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) - { - primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; - primMesh.twistEnd = primShape.PathTwist * 18 / 10; - primMesh.taperX = pathScaleX; - primMesh.taperY = pathScaleY; - - if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) - { - ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); - if (profileBegin < 0.0f) profileBegin = 0.0f; - if (profileEnd > 1.0f) profileEnd = 1.0f; - } -#if SPAM - m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); -#endif - try - { - primMesh.ExtrudeLinear(); - } - catch (Exception ex) - { - ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); - return null; - } - } - else - { - primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; - primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; - primMesh.radius = 0.01f * primShape.PathRadiusOffset; - primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; - primMesh.skew = 0.01f * primShape.PathSkew; - primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; - primMesh.twistEnd = primShape.PathTwist * 36 / 10; - primMesh.taperX = primShape.PathTaperX * 0.01f; - primMesh.taperY = primShape.PathTaperY * 0.01f; - - if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) - { - ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); - if (profileBegin < 0.0f) profileBegin = 0.0f; - if (profileEnd > 1.0f) profileEnd = 1.0f; - } -#if SPAM - m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); -#endif - try - { - primMesh.ExtrudeCircular(); - } - catch (Exception ex) - { - ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); - return null; - } - } - - primMesh.DumpRaw(baseDir, primName, "primMesh"); - - primMesh.Scale(size.X, size.Y, size.Z); - - coords = primMesh.coords; - faces = primMesh.faces; + if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) + return null; } // Remove the reference to any JPEG2000 sculpt data so it can be GCed @@ -484,10 +375,12 @@ namespace OpenSim.Region.Physics.Meshing /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimMeshData( - string primName, PrimitiveBaseShape primShape, Vector3 size, List coords, List faces) + string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) { m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); + coords = new List(); + faces = new List(); OSD meshOsd = null; if (primShape.SculptData.Length <= 0) @@ -603,8 +496,10 @@ namespace OpenSim.Region.Physics.Meshing /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimSculptData( - string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, List coords, List faces) + string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) { + coords = new List(); + faces = new List(); PrimMesher.SculptMesh sculptMesh; Image idata = null; string decodedSculptFileName = ""; @@ -711,6 +606,135 @@ namespace OpenSim.Region.Physics.Meshing return true; } + /// + /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim. + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimShapeData( + string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) + { + PrimMesh primMesh; + coords = new List(); + faces = new List(); + + float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; + float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; + float pathBegin = (float)primShape.PathBegin * 2.0e-5f; + float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; + float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; + float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; + + float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; + float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; + float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; + if (profileHollow > 0.95f) + profileHollow = 0.95f; + + int sides = 4; + if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + sides = 3; + else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + sides = 24; + else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + { // half circle, prim is a sphere + sides = 24; + + profileBegin = 0.5f * profileBegin + 0.5f; + profileEnd = 0.5f * profileEnd + 0.5f; + } + + int hollowSides = sides; + if (primShape.HollowShape == HollowShape.Circle) + hollowSides = 24; + else if (primShape.HollowShape == HollowShape.Square) + hollowSides = 4; + else if (primShape.HollowShape == HollowShape.Triangle) + hollowSides = 3; + + primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); + + if (primMesh.errorMessage != null) + if (primMesh.errorMessage.Length > 0) + m_log.Error("[ERROR] " + primMesh.errorMessage); + + primMesh.topShearX = pathShearX; + primMesh.topShearY = pathShearY; + primMesh.pathCutBegin = pathBegin; + primMesh.pathCutEnd = pathEnd; + + if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) + { + primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; + primMesh.twistEnd = primShape.PathTwist * 18 / 10; + primMesh.taperX = pathScaleX; + primMesh.taperY = pathScaleY; + + if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) + { + ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); + if (profileBegin < 0.0f) profileBegin = 0.0f; + if (profileEnd > 1.0f) profileEnd = 1.0f; + } +#if SPAM + m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); +#endif + try + { + primMesh.ExtrudeLinear(); + } + catch (Exception ex) + { + ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); + return false; + } + } + else + { + primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; + primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; + primMesh.radius = 0.01f * primShape.PathRadiusOffset; + primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; + primMesh.skew = 0.01f * primShape.PathSkew; + primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; + primMesh.twistEnd = primShape.PathTwist * 36 / 10; + primMesh.taperX = primShape.PathTaperX * 0.01f; + primMesh.taperY = primShape.PathTaperY * 0.01f; + + if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) + { + ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); + if (profileBegin < 0.0f) profileBegin = 0.0f; + if (profileEnd > 1.0f) profileEnd = 1.0f; + } +#if SPAM + m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); +#endif + try + { + primMesh.ExtrudeCircular(); + } + catch (Exception ex) + { + ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); + return false; + } + } + + primMesh.DumpRaw(baseDir, primName, "primMesh"); + + primMesh.Scale(size.X, size.Y, size.Z); + + coords = primMesh.coords; + faces = primMesh.faces; + + return true; + } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { return CreateMesh(primName, primShape, size, lod, false); -- cgit v1.1 From d917010433dda944dd1f6a7afcb827937804e805 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 03:11:36 +0100 Subject: minor: Add method doc to collision subscription methods. Change method case to reflect OpenSim standards. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 - OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 7 +++++-- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 4 ++-- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 22 +++++++++++++++++++--- 4 files changed, 26 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5791b95..58fc6fc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4821,7 +4821,6 @@ namespace OpenSim.Region.Framework.Scenes { PhysActor.OnCollisionUpdate += PhysicsCollision; PhysActor.SubscribeEvents(1000); - } } else diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 6b74e74..7766691 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1220,14 +1220,16 @@ namespace OpenSim.Region.Physics.OdePlugin { m_requestedUpdateFrequency = ms; m_eventsubscription = ms; - _parent_scene.addCollisionEventReporting(this); + _parent_scene.AddCollisionEventReporting(this); } + public override void UnSubscribeEvents() { - _parent_scene.remCollisionEventReporting(this); + _parent_scene.RemoveCollisionEventReporting(this); m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (m_eventsubscription > 0) @@ -1248,6 +1250,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_eventsubscription = 0; } } + public override bool SubscribedEvents() { if (m_eventsubscription > 0) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index b3045bd..34c0deb 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2986,12 +2986,12 @@ Console.WriteLine("changeshape not need meshing"); public override void SubscribeEvents(int ms) { m_eventsubscription = ms; - _parent_scene.addCollisionEventReporting(this); + _parent_scene.AddCollisionEventReporting(this); } public override void UnSubscribeEvents() { - _parent_scene.remCollisionEventReporting(this); + _parent_scene.RemoveCollisionEventReporting(this); m_eventsubscription = 0; } diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index cd2b156..e1e031f 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -198,7 +198,12 @@ namespace OpenSim.Region.Physics.OdePlugin private readonly List _taintedPrimL = new List(); private readonly HashSet _taintedActors = new HashSet(); private readonly List _perloopContact = new List(); + + /// + /// A list of actors that should receive collision events. + /// private readonly List _collisionEventPrim = new List(); + private readonly HashSet _badCharacter = new HashSet(); public Dictionary geom_name_map = new Dictionary(); public Dictionary actor_name_map = new Dictionary(); @@ -1604,7 +1609,11 @@ namespace OpenSim.Region.Physics.OdePlugin } // End recovered. Kitto Flora - public void addCollisionEventReporting(PhysicsActor obj) + /// + /// Add actor to the list that should receive collision events in the simulate loop. + /// + /// + public void AddCollisionEventReporting(PhysicsActor obj) { lock (_collisionEventPrim) { @@ -1613,7 +1622,11 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public void remCollisionEventReporting(PhysicsActor obj) + /// + /// Remove actor from the list that should receive collision events in the simulate loop. + /// + /// + public void RemoveCollisionEventReporting(PhysicsActor obj) { lock (_collisionEventPrim) { @@ -2132,7 +2145,7 @@ namespace OpenSim.Region.Physics.OdePlugin //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); lock (prim) { - remCollisionEventReporting(prim); + RemoveCollisionEventReporting(prim); lock (ode) { if (prim.prim_geom != IntPtr.Zero) @@ -2792,6 +2805,8 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); if (obj == null) continue; +// m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName); + switch ((ActorTypes)obj.PhysicsActorType) { case ActorTypes.Agent: @@ -2799,6 +2814,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); cobj.AddCollisionFrameTime(100); cobj.SendCollisions(); break; + case ActorTypes.Prim: OdePrim pobj = (OdePrim)obj; pobj.SendCollisions(); -- cgit v1.1 From 9fc59e2bf230b94d7efebedffff37724d64bb59a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 03:19:00 +0100 Subject: minor: remove some mono compiler warnings --- OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs index 29fd1a4..4c33db5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static Int32 m_counter = 0; - private Int32 m_identifier; +// private Int32 m_identifier; /// /// Number of ticks (ms) per quantum, drip rate and max burst @@ -173,7 +173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// second. If zero, the bucket always remains full public TokenBucket(TokenBucket parent, Int64 dripRate) { - m_identifier = m_counter++; +// m_identifier = m_counter++; + m_counter++; Parent = parent; RequestedDripRate = dripRate; @@ -320,7 +321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public class AdaptiveTokenBucket : TokenBucket { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// The minimum rate for flow control. Minimum drip rate is one -- cgit v1.1 From 49a3740ee9983ffa99a81924aa01071f4dc13a6b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 03:56:29 +0100 Subject: minor: remove mono compiler warnings, some code spacing adjustments --- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 5 ++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 2 +- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 8 +++----- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 7766691..4f461ad 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1229,11 +1229,14 @@ namespace OpenSim.Region.Physics.OdePlugin m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } - + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (m_eventsubscription > 0) { +// m_log.DebugFormat( +// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 34c0deb..44eafb7 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1457,7 +1457,6 @@ Console.WriteLine("changeadd 1"); { if (m_isphysical) { - if (!m_disabled && !m_taintremove && !childPrim) { if (Body == IntPtr.Zero) @@ -2999,6 +2998,7 @@ Console.WriteLine("changeshape not need meshing"); { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index e1e031f..8a24190 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -100,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin Rubber = 6 } - public sealed class OdeScene : PhysicsScene + public class OdeScene : PhysicsScene { private readonly ILog m_log; // private Dictionary m_storedCollisions = new Dictionary(); @@ -957,7 +957,6 @@ namespace OpenSim.Region.Physics.OdePlugin character.SetPidStatus(true); } } - if (p1.PhysicsActorType == (int) ActorTypes.Agent) { @@ -1058,9 +1057,7 @@ namespace OpenSim.Region.Physics.OdePlugin { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; - } - } else { @@ -1083,7 +1080,6 @@ namespace OpenSim.Region.Physics.OdePlugin { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; - } } } @@ -1295,6 +1291,7 @@ namespace OpenSim.Region.Physics.OdePlugin //returncollisions = true; break; + case ActorTypes.Prim: if (p1 is OdePrim) { @@ -1322,6 +1319,7 @@ namespace OpenSim.Region.Physics.OdePlugin cc2.AddCollisionEvent(obj2LocalID, contact); break; + case ActorTypes.Prim: if (p2 is OdePrim) -- cgit v1.1 From 4f4d0804618e5560964df90e5c5302b9fba8163d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 23:20:43 +0100 Subject: refactor: Rename ODEPrim.ParentPrim() to AddChildPrim() for code readability --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 44eafb7..9c323a4 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -778,6 +778,7 @@ namespace OpenSim.Region.Physics.OdePlugin Body = IntPtr.Zero; } } + m_disabled = true; m_collisionscore = 0; } @@ -968,7 +969,7 @@ Console.WriteLine("ZProcessTaints for " + Name); OdePrim obj = (OdePrim)m_taintparent; //obj.disableBody(); //Console.WriteLine("changelink calls ParentPrim"); - obj.ParentPrim(this); + obj.AddChildPrim(this); /* if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) @@ -1008,11 +1009,13 @@ Console.WriteLine("ZProcessTaints for " + Name); m_taintPhysics = m_isphysical; } - // I'm the parent - // prim is the child - public void ParentPrim(OdePrim prim) + /// + /// Add a child prim to this parent prim. + /// + /// Child prim + public void AddChildPrim(OdePrim prim) { -//Console.WriteLine("ParentPrim " + Name); +//Console.WriteLine("AddChildPrim " + Name); if (this.m_localID != prim.m_localID) { if (Body == IntPtr.Zero) @@ -1035,7 +1038,6 @@ Console.WriteLine("ZProcessTaints for " + Name); d.MassSetZero(out m2); d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); - d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; @@ -1105,6 +1107,7 @@ Console.WriteLine("ZProcessTaints for " + Name); prm.Body = Body; _parent_scene.addActivePrim(prm); } + m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); @@ -1113,7 +1116,6 @@ Console.WriteLine("ZProcessTaints for " + Name); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; @@ -1135,7 +1137,6 @@ Console.WriteLine("ZProcessTaints for " + Name); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); - m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; @@ -1146,7 +1147,9 @@ Console.WriteLine("ZProcessTaints for " + Name); createAMotor(m_angularlock); } d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); - if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); + if (m_vehicle.Type != Vehicle.TYPE_NONE) + m_vehicle.Enable(Body, _parent_scene); + _parent_scene.addActivePrim(this); } } @@ -1183,7 +1186,7 @@ Console.WriteLine("ZProcessTaints for " + Name); foreach (OdePrim prm in childrenPrim) { //Console.WriteLine("ChildSetGeom calls ParentPrim"); - ParentPrim(prm); + AddChildPrim(prm); } } @@ -1223,7 +1226,7 @@ Console.WriteLine("ZProcessTaints for " + Name); foreach (OdePrim prm in childrenPrim) { //Console.WriteLine("ChildDelink calls ParentPrim"); - ParentPrim(prm); + AddChildPrim(prm); } } } -- cgit v1.1 From e08be91c846d898fdc79a88e79ac1feb491cb63d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jul 2011 23:44:47 +0100 Subject: Refactor: Replace instances of m_isphysical with IsPhysical rather than have some code reference the private var and other the public var without any functionality difference. Add some method doc to IsPhysical --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 73 ++++++++++++++++------------- 1 file changed, 40 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 9c323a4..879d30f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -61,6 +61,22 @@ namespace OpenSim.Region.Physics.OdePlugin { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool m_isphysical; + + /// + /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. + /// + public override bool IsPhysical + { + get { return m_isphysical; } + set + { + m_isphysical = value; + if (!m_isphysical) // Zero the remembered last velocity + m_lastVelocity = Vector3.Zero; + } + } + private Vector3 _position; private Vector3 _velocity; private Vector3 _torque; @@ -153,7 +169,6 @@ namespace OpenSim.Region.Physics.OdePlugin private List childrenPrim = new List(); private bool iscolliding; - private bool m_isphysical; private bool m_isSelected; internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively @@ -240,13 +255,15 @@ namespace OpenSim.Region.Physics.OdePlugin m_targetSpace = (IntPtr)0; if (pos.Z < 0) - m_isphysical = false; + { + IsPhysical = false; + } else { - m_isphysical = pisPhysical; + IsPhysical = pisPhysical; // If we're physical, we need to be in the master space for now. // linksets *should* be in a space together.. but are not currently - if (m_isphysical) + if (IsPhysical) m_targetSpace = _parent_scene.space; } @@ -289,7 +306,7 @@ namespace OpenSim.Region.Physics.OdePlugin // through it while it's selected m_collisionscore = 0; - if ((m_isphysical && !_zeroFlag) || !value) + if ((IsPhysical && !_zeroFlag) || !value) { m_taintselected = value; _parent_scene.AddPhysicsActorTaint(this); @@ -332,7 +349,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (!childPrim) { - if (m_isphysical && Body != IntPtr.Zero) + if (IsPhysical && Body != IntPtr.Zero) { d.BodyEnable(Body); if (m_vehicle.Type != Vehicle.TYPE_NONE) @@ -347,7 +364,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_disabled = true; - if (m_isphysical && Body != IntPtr.Zero) + if (IsPhysical && Body != IntPtr.Zero) { d.BodyDisable(Body); } @@ -887,7 +904,7 @@ Console.WriteLine("ZProcessTaints for " + Name); } } - if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) + if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) changePhysicsStatus(timestep); if (!_size.ApproxEquals(m_taintsize, 0f)) @@ -1006,7 +1023,7 @@ Console.WriteLine("ZProcessTaints for " + Name); } _parent = m_taintparent; - m_taintPhysics = m_isphysical; + m_taintPhysics = IsPhysical; } /// @@ -1159,7 +1176,7 @@ Console.WriteLine("ZProcessTaints for " + Name); private void ChildSetGeom(OdePrim odePrim) { - //if (m_isphysical && Body != IntPtr.Zero) + //if (IsPhysical && Body != IntPtr.Zero) lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) @@ -1260,7 +1277,7 @@ Console.WriteLine("ZProcessTaints for " + Name); // first 50 again. then the last 50 are disabled. then the first 50, which were just woken // up, start simulating again, which in turn wakes up the last 50. - if (m_isphysical) + if (IsPhysical) { disableBodySoft(); } @@ -1271,7 +1288,7 @@ Console.WriteLine("ZProcessTaints for " + Name); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } - if (m_isphysical) + if (IsPhysical) { disableBodySoft(); } @@ -1280,7 +1297,7 @@ Console.WriteLine("ZProcessTaints for " + Name); { m_collisionCategories = CollisionCategories.Geom; - if (m_isphysical) + if (IsPhysical) m_collisionCategories |= CollisionCategories.Body; m_collisionFlags = m_default_collisionFlags; @@ -1295,7 +1312,8 @@ Console.WriteLine("ZProcessTaints for " + Name); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } - if (m_isphysical) + + if (IsPhysical) { if (Body != IntPtr.Zero) { @@ -1314,7 +1332,7 @@ Console.WriteLine("ZProcessTaints for " + Name); { m_taintposition = _position; m_taintrot = _orientation; - m_taintPhysics = m_isphysical; + m_taintPhysics = IsPhysical; m_taintselected = m_isSelected; m_taintsize = _size; m_taintshape = false; @@ -1442,7 +1460,7 @@ Console.WriteLine("changeadd 1"); d.GeomSetQuaternion(prim_geom, ref myrot); } - if (m_isphysical && Body == IntPtr.Zero) + if (IsPhysical && Body == IntPtr.Zero) { enableBody(); } @@ -1458,7 +1476,7 @@ Console.WriteLine("changeadd 1"); public void changemove(float timestep) { - if (m_isphysical) + if (IsPhysical) { if (!m_disabled && !m_taintremove && !childPrim) { @@ -1791,7 +1809,7 @@ Console.WriteLine(" JointCreateFixed"); { // KF: If this is a root prim do BodySet d.BodySetQuaternion(Body, ref myrot); - if (m_isphysical) + if (IsPhysical) { if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) createAMotor(m_angularlock); @@ -1828,7 +1846,7 @@ Console.WriteLine(" JointCreateFixed"); public void changePhysicsStatus(float timestep) { - if (m_isphysical == true) + if (IsPhysical) { if (Body == IntPtr.Zero) { @@ -1848,8 +1866,6 @@ Console.WriteLine(" JointCreateFixed"); { if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) { - - if (prim_geom != IntPtr.Zero) { try @@ -1867,6 +1883,7 @@ Console.WriteLine(" JointCreateFixed"); //Console.WriteLine("changePhysicsStatus for " + Name); changeadd(2f); } + if (childPrim) { if (_parent != null) @@ -1885,7 +1902,7 @@ Console.WriteLine(" JointCreateFixed"); changeSelectedStatus(timestep); resetCollisionAccounting(); - m_taintPhysics = m_isphysical; + m_taintPhysics = IsPhysical; } public void changesize(float timestamp) @@ -2218,16 +2235,6 @@ Console.WriteLine("changeshape not need meshing"); m_taintVelocity = Vector3.Zero; } - public override bool IsPhysical - { - get { return m_isphysical; } - set { - m_isphysical = value; - if (!m_isphysical) // Zero the remembered last velocity - m_lastVelocity = Vector3.Zero; - } - } - public void setPrimForRemoval() { m_taintremove = true; @@ -2406,7 +2413,7 @@ Console.WriteLine("changeshape not need meshing"); { get { - if (!m_isphysical || Body == IntPtr.Zero) + if (!IsPhysical || Body == IntPtr.Zero) return Vector3.Zero; return _torque; -- cgit v1.1 From f1ce17071dfed560d4785f7b2aabaf25f241f81f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 00:43:02 +0100 Subject: minor: method doc --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 23 ++++++++++++++++++++--- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 1 - 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 879d30f..e91ee51 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -157,7 +157,12 @@ namespace OpenSim.Region.Physics.OdePlugin private IMesh _mesh; private PrimitiveBaseShape _pbs; private OdeScene _parent_scene; + + /// + /// The physics space which contains prim geometries + /// public IntPtr m_targetSpace = IntPtr.Zero; + public IntPtr prim_geom; public IntPtr prev_geom; public IntPtr _triMeshData; @@ -223,7 +228,6 @@ namespace OpenSim.Region.Physics.OdePlugin // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; body_autodisable_frames = parent_scene.bodyFramesAutoDisable; - prim_geom = IntPtr.Zero; prev_geom = IntPtr.Zero; @@ -322,6 +326,10 @@ namespace OpenSim.Region.Physics.OdePlugin } } + /// + /// Set a new geometry for this prim. + /// + /// public void SetGeom(IntPtr geom) { prev_geom = prim_geom; @@ -370,6 +378,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } + /// + /// Make a prim subject to physics. + /// public void enableBody() { // Don't enable this body if we're a child prim @@ -745,6 +756,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } + /// + /// Stop a prim from being subject to physics. + /// public void disableBody() { //this kills the body so things like 'mesh' can re-create it. @@ -1192,7 +1206,6 @@ Console.WriteLine("ZProcessTaints for " + Name); } disableBody(); - if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); @@ -1206,7 +1219,6 @@ Console.WriteLine("ZProcessTaints for " + Name); AddChildPrim(prm); } } - } private void ChildDelink(OdePrim odePrim) @@ -1341,6 +1353,11 @@ Console.WriteLine("ZProcessTaints for " + Name); m_taintVelocity = Vector3.Zero; } + /// + /// Create a geometry for the given mesh in the given target space. + /// + /// + /// /param> public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) { #if SPAM diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 8a24190..3c702db 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -305,7 +305,6 @@ namespace OpenSim.Region.Physics.OdePlugin world = d.WorldCreate(); space = d.HashSpaceCreate(IntPtr.Zero); - contactgroup = d.JointGroupCreate(0); //contactgroup -- cgit v1.1 From 454312f5bc7e301d44e37f56a1078b8ff020bf5d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 00:44:23 +0100 Subject: refactor: rename CreateGeom _mesh argument to mesh, so as to not confuse this with the pre-existing _mesh field --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index e91ee51..905522d 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1358,14 +1358,14 @@ Console.WriteLine("ZProcessTaints for " + Name); /// /// /// /param> - public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) + public void CreateGeom(IntPtr m_targetSpace, IMesh mesh) { #if SPAM Console.WriteLine("CreateGeom:"); #endif - if (_mesh != null) + if (mesh != null) { - setMesh(_parent_scene, _mesh); + setMesh(_parent_scene, mesh); } else { -- cgit v1.1 From 196a774b2453c71403f74959b710335109edfe1a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 00:45:20 +0100 Subject: minor: correct method doc for last commit --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 905522d..712f7cd 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1357,7 +1357,7 @@ Console.WriteLine("ZProcessTaints for " + Name); /// Create a geometry for the given mesh in the given target space. /// /// - /// /param> + /// /param> public void CreateGeom(IntPtr m_targetSpace, IMesh mesh) { #if SPAM -- cgit v1.1 From bd8f538f800afeffdb6b8ced11e65940921424ab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 00:49:49 +0100 Subject: refactor: Remove argument to pass in an initial mesh to OdePrim since this is no longer required and it prevents removal of the _mesh field (which is only used temporarily) If passing in a mesh becomes important again in the future then this can be reinstated. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 3 +-- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 29 ++++------------------------ 2 files changed, 5 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 712f7cd..cd6a0fb 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -208,7 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin internal int m_material = (int)Material.Wood; public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, - Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) + Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) { Name = primName; m_vehicle = new ODEDynamics(); @@ -252,7 +252,6 @@ namespace OpenSim.Region.Physics.OdePlugin _orientation = rotation; m_taintrot = _orientation; - _mesh = mesh; _pbs = pbs; _parent_scene = parent_scene; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 3c702db..1d4a28e 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -304,7 +304,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Create the world and the first space world = d.WorldCreate(); space = d.HashSpaceCreate(IntPtr.Zero); - + contactgroup = d.JointGroupCreate(0); //contactgroup @@ -1687,7 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin } private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, - IMesh mesh, PrimitiveBaseShape pbs, bool isphysical, uint localID) + PrimitiveBaseShape pbs, bool isphysical, uint localID) { Vector3 pos = position; Vector3 siz = size; @@ -1696,7 +1696,7 @@ namespace OpenSim.Region.Physics.OdePlugin OdePrim newPrim; lock (OdeLock) { - newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); + newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, ode); lock (_prims) _prims.Add(newPrim); @@ -1724,28 +1724,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); #endif - PhysicsActor result; - IMesh mesh = null; - - // Don't create the mesh here - wait until the mesh data is loaded from the asset store. -// if (needsMeshing(pbs)) -// { -// try -// { -// mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); -// } -// catch(Exception e) -// { -// m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName); -// m_log.Debug(e.ToString()); -// mesh = null; -// return null; -// } -// } - - result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid); - - return result; + return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); } public override float TimeDilation -- cgit v1.1 From d0412765172e9431813dee3a30473c8f28c184bc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 01:03:52 +0100 Subject: Remove _mesh field since the mesh data no longer needs to be stored after it's initially used. This may improve memory usage for regions using mesh and sculpts, though I suspect that it doesn't address the current memory leak. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 65 +++++++---------------------- 1 file changed, 16 insertions(+), 49 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index cd6a0fb..fdb95cf 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -154,7 +154,6 @@ namespace OpenSim.Region.Physics.OdePlugin private List m_forcelist = new List(); private List m_angularforcelist = new List(); - private IMesh _mesh; private PrimitiveBaseShape _pbs; private OdeScene _parent_scene; @@ -1356,7 +1355,7 @@ Console.WriteLine("ZProcessTaints for " + Name); /// Create a geometry for the given mesh in the given target space. /// /// - /// /param> + /// If null, then a mesh is used that is based on the profile shape data. public void CreateGeom(IntPtr m_targetSpace, IMesh mesh) { #if SPAM @@ -1447,15 +1446,14 @@ Console.WriteLine("CreateGeom:"); m_targetSpace = targetspace; - if (_mesh == null) + IMesh mesh = null; + + if (_parent_scene.needsMeshing(_pbs)) { - if (_parent_scene.needsMeshing(_pbs)) - { - // Don't need to re-enable body.. it's done in SetMesh - _mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); - // createmesh returns null when it's a shape that isn't a cube. - // m_log.Debug(m_localID); - } + // Don't need to re-enable body.. it's done in SetMesh + mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); + // createmesh returns null when it's a shape that isn't a cube. + // m_log.Debug(m_localID); } lock (_parent_scene.OdeLock) @@ -1463,7 +1461,7 @@ Console.WriteLine("CreateGeom:"); #if SPAM Console.WriteLine("changeadd 1"); #endif - CreateGeom(m_targetSpace, _mesh); + CreateGeom(m_targetSpace, mesh); if (prim_geom != IntPtr.Zero) { @@ -1888,7 +1886,6 @@ Console.WriteLine(" JointCreateFixed"); { d.GeomDestroy(prim_geom); prim_geom = IntPtr.Zero; - _mesh = null; } catch (System.AccessViolationException) { @@ -1933,12 +1930,6 @@ Console.WriteLine(" JointCreateFixed"); if (_size.Y <= 0) _size.Y = 0.01f; if (_size.Z <= 0) _size.Z = 0.01f; - // Cleanup of old prim geometry - if (_mesh != null) - { - // TODO: Cleanup meshing here - } - //kill body to rebuild if (IsPhysical && Body != IntPtr.Zero) { @@ -1966,6 +1957,8 @@ Console.WriteLine(" JointCreateFixed"); prim_geom = IntPtr.Zero; // we don't need to do space calculation because the client sends a position update also. + IMesh mesh = null; + // Construction of new prim if (_parent_scene.needsMeshing(_pbs)) { @@ -1975,27 +1968,11 @@ Console.WriteLine(" JointCreateFixed"); meshlod = _parent_scene.MeshSculptphysicalLOD; // Don't need to re-enable body.. it's done in SetMesh - IMesh mesh = null; - if (_parent_scene.needsMeshing(_pbs)) mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); - -#if SPAM -Console.WriteLine("changesize 1"); -#endif - CreateGeom(m_targetSpace, mesh); - } - else - { - _mesh = null; - -#if SPAM -Console.WriteLine("changesize 2"); -#endif - - CreateGeom(m_targetSpace, _mesh); } + CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; @@ -2083,6 +2060,8 @@ Console.WriteLine("changesize 2"); if (_size.Z <= 0) _size.Z = 0.01f; // Construction of new prim + IMesh mesh = null; + if (_parent_scene.needsMeshing(_pbs)) { // Don't need to re-enable body.. it's done in CreateMesh @@ -2092,22 +2071,10 @@ Console.WriteLine("changesize 2"); meshlod = _parent_scene.MeshSculptphysicalLOD; // createmesh returns null when it doesn't mesh. - IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); -#if SPAM -Console.WriteLine("changeshape needed meshing"); -#endif - CreateGeom(m_targetSpace, mesh); - } - else - { - _mesh = null; - -#if SPAM -Console.WriteLine("changeshape not need meshing"); -#endif - CreateGeom(m_targetSpace, null); + mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); } + CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); //myrot.W = _orientation.w; -- cgit v1.1 From aea700753361621f25a3e22f4176fcd2cc981b9f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 02:50:50 +0100 Subject: refactor: split out ninja joint part of SOP.DoPhysicsPropertyUpdate() so that we don't have to look at it if it's not relevant --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 157 +++++++++++---------- 1 file changed, 86 insertions(+), 71 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 58fc6fc..7c9636a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1751,96 +1751,111 @@ namespace OpenSim.Region.Framework.Scenes return part; } - public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) + /// + /// Do a physics property update for a NINJA joint. + /// + /// + /// + protected void DoPhysicsPropertyUpdateForNinjaJoint(bool UsePhysics, bool isNew) { - if (IsJoint()) + if (UsePhysics) { - if (UsePhysics) - { - // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene. - // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical. + // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene. + // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical. - PhysicsJointType jointType; - if (IsHingeJoint()) - { - jointType = PhysicsJointType.Hinge; - } - else if (IsBallJoint()) - { - jointType = PhysicsJointType.Ball; - } - else - { - jointType = PhysicsJointType.Ball; - } + PhysicsJointType jointType; + if (IsHingeJoint()) + { + jointType = PhysicsJointType.Hinge; + } + else if (IsBallJoint()) + { + jointType = PhysicsJointType.Ball; + } + else + { + jointType = PhysicsJointType.Ball; + } - List bodyNames = new List(); - string RawParams = Description; - string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); - string trackedBodyName = null; - if (jointParams.Length >= 2) + List bodyNames = new List(); + string RawParams = Description; + string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + string trackedBodyName = null; + if (jointParams.Length >= 2) + { + for (int iBodyName = 0; iBodyName < 2; iBodyName++) { - for (int iBodyName = 0; iBodyName < 2; iBodyName++) + string bodyName = jointParams[iBodyName]; + bodyNames.Add(bodyName); + if (bodyName != "NULL") { - string bodyName = jointParams[iBodyName]; - bodyNames.Add(bodyName); - if (bodyName != "NULL") + if (trackedBodyName == null) { - if (trackedBodyName == null) - { - trackedBodyName = bodyName; - } + trackedBodyName = bodyName; } } } + } - SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup - Quaternion localRotation = Quaternion.Identity; - if (trackedBody != null) - { - localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; - } - else - { - // error, output it below - } + SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup + Quaternion localRotation = Quaternion.Identity; + if (trackedBody != null) + { + localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; + } + else + { + // error, output it below + } - PhysicsJoint joint; + PhysicsJoint joint; - joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, - AbsolutePosition, - this.RotationOffset, - Description, - bodyNames, - trackedBodyName, - localRotation); + joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, + AbsolutePosition, + this.RotationOffset, + Description, + bodyNames, + trackedBodyName, + localRotation); - if (trackedBody == null) - { - ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); - } + if (trackedBody == null) + { + ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); + } + } + else + { + if (isNew) + { + // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to + // delete, and if we try to delete it, due to asynchronous processing, the deletion request + // will get processed later at an indeterminate time, which could cancel a later-arriving + // joint creation request. } else { - if (isNew) - { - // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to - // delete, and if we try to delete it, due to asynchronous processing, the deletion request - // will get processed later at an indeterminate time, which could cancel a later-arriving - // joint creation request. - } - else - { - // here we turn off the joint object, so remove the joint from the physics scene - m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed? + // here we turn off the joint object, so remove the joint from the physics scene + m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed? - // make sure client isn't interpolating the joint proxy object - Velocity = Vector3.Zero; - AngularVelocity = Vector3.Zero; - Acceleration = Vector3.Zero; - } + // make sure client isn't interpolating the joint proxy object + Velocity = Vector3.Zero; + AngularVelocity = Vector3.Zero; + Acceleration = Vector3.Zero; } } + } + + /// + /// Do a physics propery update for this part. + /// + /// + /// + public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) + { + if (IsJoint()) + { + DoPhysicsPropertyUpdateForNinjaJoint(UsePhysics, isNew); + } else { if (PhysActor != null) @@ -4699,7 +4714,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CheckSculptAndLoad() { -// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); + m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); if (ParentGroup.IsDeleted) return; -- cgit v1.1 From b757583662e75380d70e7462a3b0f6a6d6732a02 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 31 Jul 2011 03:41:35 +0100 Subject: Comment out SOP logging message I accidentally left in --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7c9636a..90ad34e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4714,7 +4714,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CheckSculptAndLoad() { - m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); +// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); if (ParentGroup.IsDeleted) return; -- cgit v1.1 From 210296482634aa2f99f01a2b2990b581ef45eeb6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 05:14:16 +0100 Subject: minor: indentation correction --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 30 ++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 1d4a28e..c1c4d11 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -3482,24 +3482,21 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); float hfmin = 2000; float hfmax = -2000; - for (int x = 0; x < heightmapWidthSamples; x++) + for (int x = 0; x < heightmapWidthSamples; x++) + { + for (int y = 0; y < heightmapHeightSamples; y++) { - for (int y = 0; y < heightmapHeightSamples; y++) - { - int xx = Util.Clip(x - 1, 0, regionsize - 1); - int yy = Util.Clip(y - 1, 0, regionsize - 1); - - - float val= heightMap[yy * (int)Constants.RegionSize + xx]; - _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; - - hfmin = (val < hfmin) ? val : hfmin; - hfmax = (val > hfmax) ? val : hfmax; - } + int xx = Util.Clip(x - 1, 0, regionsize - 1); + int yy = Util.Clip(y - 1, 0, regionsize - 1); + + + float val= heightMap[yy * (int)Constants.RegionSize + xx]; + _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; + + hfmin = (val < hfmin) ? val : hfmin; + hfmax = (val > hfmax) ? val : hfmax; } - - - + } lock (OdeLock) { @@ -3554,7 +3551,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); - } } -- cgit v1.1 From dfa2f7d7151ec0e3835c4a008897389353be1cb3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 05:34:02 +0100 Subject: If a prim changes size or shape, add actor to _parent_scene.actor_name_map with new prim_geom key, as the old one becomes invalid. This resolves http://opensimulator.org/mantis/view.php?id=5603 where changing size or shape would stop collision_start being fired in a running script. In both this and existing code we are not removing old actors from actor_name_map when the existing prim_geom is removed, which leads to a small memory leak over time. This needs to be fixed. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index fdb95cf..e18e1b4 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1481,7 +1481,7 @@ Console.WriteLine("changeadd 1"); } _parent_scene.geom_name_map[prim_geom] = this.Name; - _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; + _parent_scene.actor_name_map[prim_geom] = this; changeSelectedStatus(timestep); @@ -1991,6 +1991,7 @@ Console.WriteLine(" JointCreateFixed"); } _parent_scene.geom_name_map[prim_geom] = oldname; + _parent_scene.actor_name_map[prim_geom] = this; changeSelectedStatus(timestamp); if (childPrim) @@ -2095,7 +2096,9 @@ Console.WriteLine(" JointCreateFixed"); d.BodyEnable(Body); } } + _parent_scene.geom_name_map[prim_geom] = oldname; + _parent_scene.actor_name_map[prim_geom] = this; changeSelectedStatus(timestamp); if (childPrim) -- cgit v1.1 From 509200d5cd0646a75eaa200165bbae85e09b4380 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 05:48:27 +0100 Subject: minor: add note to RemovePrimThreadLocked() to the effect that it contrary to the summary, it is being called from within Simulate() lock (OdeLock) --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 2 +- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index e18e1b4..61408f0 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1352,7 +1352,7 @@ Console.WriteLine("ZProcessTaints for " + Name); } /// - /// Create a geometry for the given mesh in the given target space. + /// Create a geometry for the given mesh/shape in the given target space. /// /// /// If null, then a mesh is used that is based on the profile shape data. diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index c1c4d11..4419dff 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2110,6 +2110,9 @@ namespace OpenSim.Region.Physics.OdePlugin /// /// This is called from within simulate but outside the locked portion /// We need to do our own locking here + /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in + /// Simulate() -- justincc). + /// /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. /// /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory -- cgit v1.1 From 6618948ff9b1e98b52f3067855ca1b05e7e36144 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 06:15:02 +0100 Subject: refactor: centralize prim geom removal code from four places to one --- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 4 ++ OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 63 +++++++++++++++----------- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 24 +++------- 3 files changed, 48 insertions(+), 43 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 3870411..04efc1d 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -86,6 +86,10 @@ namespace OpenSim.Region.Physics.Manager public abstract void RemoveAvatar(PhysicsActor actor); + /// + /// Remove a prim from the physics scene. + /// + /// public abstract void RemovePrim(PhysicsActor prim); public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 61408f0..e90df48 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1352,7 +1352,7 @@ Console.WriteLine("ZProcessTaints for " + Name); } /// - /// Create a geometry for the given mesh/shape in the given target space. + /// Create a geometry for the given mesh in the given target space. /// /// /// If null, then a mesh is used that is based on the profile shape data. @@ -1436,6 +1436,36 @@ Console.WriteLine("CreateGeom:"); } } + /// + /// Remove the existing geom from this prim. + /// + /// + /// If null, then a mesh is used that is based on the profile shape data. + /// true if the geom was successfully removed, false if it was already gone or the remove failed. + public bool RemoveGeom() + { + if (prim_geom != IntPtr.Zero) + { + try + { + d.GeomDestroy(prim_geom); + prim_geom = IntPtr.Zero; + } + catch (System.AccessViolationException) + { + prim_geom = IntPtr.Zero; + m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); + return false; + } + + return true; + } + else + { + return false; + } + } + public void changeadd(float timestep) { int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); @@ -1880,19 +1910,8 @@ Console.WriteLine(" JointCreateFixed"); { if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) { - if (prim_geom != IntPtr.Zero) - { - try - { - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); - } - } + RemoveGeom(); + //Console.WriteLine("changePhysicsStatus for " + Name); changeadd(2f); } @@ -1953,8 +1972,8 @@ Console.WriteLine(" JointCreateFixed"); d.SpaceRemove(m_targetSpace, prim_geom); } - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; + RemoveGeom(); + // we don't need to do space calculation because the client sends a position update also. IMesh mesh = null; @@ -2044,17 +2063,9 @@ Console.WriteLine(" JointCreateFixed"); disableBody(); } } - try - { - d.GeomDestroy(prim_geom); - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); - } - prim_geom = IntPtr.Zero; + RemoveGeom(); + // we don't need to do space calculation because the client sends a position update also. if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 4419dff..3402be2 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2094,6 +2094,8 @@ namespace OpenSim.Region.Physics.OdePlugin public override void RemovePrim(PhysicsActor prim) { + // As with all ODE physics operations, we don't remove the prim immediately but signal that it should be + // removed in the next physics simulate pass. if (prim is OdePrim) { lock (OdeLock) @@ -2169,24 +2171,12 @@ namespace OpenSim.Region.Physics.OdePlugin //} //} //m_log.Warn(prim.prim_geom); - try - { - if (prim.prim_geom != IntPtr.Zero) - { - d.GeomDestroy(prim.prim_geom); - prim.prim_geom = IntPtr.Zero; - } - else - { - m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); - } - } - catch (AccessViolationException) - { - m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); - } + + if (!prim.RemoveGeom()) + m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); + lock (_prims) - _prims.Remove(prim); + _prims.Remove(prim); //If there are no more geometries in the sub-space, we don't need it in the main space anymore //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) -- cgit v1.1 From f32dbef64715bb389a0aa8cd7d2a994e6b168b61 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 06:32:30 +0100 Subject: When an ODE geom is removed (as when a non-phantom prim is deleted, resized or shape changed, also remove the OdeScene.actor_name_map entry pointing to the phys actor This is to stop a small memory leak over time when prims are deleted or phantom-toggled --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index e90df48..16764c2 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1448,6 +1448,7 @@ Console.WriteLine("CreateGeom:"); { try { + _parent_scene.actor_name_map.Remove(prim_geom); d.GeomDestroy(prim_geom); prim_geom = IntPtr.Zero; } @@ -1455,6 +1456,7 @@ Console.WriteLine("CreateGeom:"); { prim_geom = IntPtr.Zero; m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); + return false; } -- cgit v1.1 From f79df6f43f76fee577e987d1b931b4e30ad8b0d5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 06:35:59 +0100 Subject: remove the unused ODEPrim.prev_geom field --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 3 --- 1 file changed, 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 16764c2..345156e 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -163,7 +163,6 @@ namespace OpenSim.Region.Physics.OdePlugin public IntPtr m_targetSpace = IntPtr.Zero; public IntPtr prim_geom; - public IntPtr prev_geom; public IntPtr _triMeshData; private IntPtr _linkJointGroup = IntPtr.Zero; @@ -228,7 +227,6 @@ namespace OpenSim.Region.Physics.OdePlugin body_autodisable_frames = parent_scene.bodyFramesAutoDisable; prim_geom = IntPtr.Zero; - prev_geom = IntPtr.Zero; if (!pos.IsFinite()) { @@ -330,7 +328,6 @@ namespace OpenSim.Region.Physics.OdePlugin /// public void SetGeom(IntPtr geom) { - prev_geom = prim_geom; prim_geom = geom; //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); if (prim_geom != IntPtr.Zero) -- cgit v1.1 From ccb4b762427f8f9c88b8d26a250acb96b32ea807 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 06:40:29 +0100 Subject: On geom removal, remove the name from the OdeScene.geom_name_map too --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 345156e..8881c44 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1445,6 +1445,7 @@ Console.WriteLine("CreateGeom:"); { try { + _parent_scene.geom_name_map.Remove(prim_geom); _parent_scene.actor_name_map.Remove(prim_geom); d.GeomDestroy(prim_geom); prim_geom = IntPtr.Zero; -- cgit v1.1 From 40a78db1828cfd9b159cfc0f0fc64409aa2d1489 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 06:47:45 +0100 Subject: comment out unused code in OdeScene.TriCallback() --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 3402be2..6e603e8 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1423,18 +1423,18 @@ namespace OpenSim.Region.Physics.OdePlugin public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) { - String name1 = null; - String name2 = null; - - if (!geom_name_map.TryGetValue(trimesh, out name1)) - { - name1 = "null"; - } - - if (!geom_name_map.TryGetValue(refObject, out name2)) - { - name2 = "null"; - } +// String name1 = null; +// String name2 = null; +// +// if (!geom_name_map.TryGetValue(trimesh, out name1)) +// { +// name1 = "null"; +// } +// +// if (!geom_name_map.TryGetValue(refObject, out name2)) +// { +// name2 = "null"; +// } // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); -- cgit v1.1 From f9d6a91252366df40ab44220538c9b691156f801 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 06:52:52 +0100 Subject: Instead of preserving old name in geom_name_map in change size or shape, use the Name property instead. This is equivalent since the prim 'name' is never changed. In fact, this propery is never used for prims --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 8881c44..0128cbc 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1510,7 +1510,7 @@ Console.WriteLine("changeadd 1"); } } - _parent_scene.geom_name_map[prim_geom] = this.Name; + _parent_scene.geom_name_map[prim_geom] = Name; _parent_scene.actor_name_map[prim_geom] = this; changeSelectedStatus(timestep); @@ -1943,8 +1943,6 @@ Console.WriteLine(" JointCreateFixed"); m_log.DebugFormat("[ODE PRIM]: Called changesize"); #endif - string oldname = _parent_scene.geom_name_map[prim_geom]; - if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; if (_size.Z <= 0) _size.Z = 0.01f; @@ -2009,7 +2007,7 @@ Console.WriteLine(" JointCreateFixed"); d.BodyEnable(Body); } - _parent_scene.geom_name_map[prim_geom] = oldname; + _parent_scene.geom_name_map[prim_geom] = Name; _parent_scene.actor_name_map[prim_geom] = this; changeSelectedStatus(timestamp); @@ -2045,8 +2043,6 @@ Console.WriteLine(" JointCreateFixed"); public void changeshape(float timestamp) { - string oldname = _parent_scene.geom_name_map[prim_geom]; - // Cleanup of old prim geometry and Bodies if (IsPhysical && Body != IntPtr.Zero) { @@ -2108,7 +2104,7 @@ Console.WriteLine(" JointCreateFixed"); } } - _parent_scene.geom_name_map[prim_geom] = oldname; + _parent_scene.geom_name_map[prim_geom] = Name; _parent_scene.actor_name_map[prim_geom] = this; changeSelectedStatus(timestamp); -- cgit v1.1 From 05e94ff27e5dea6283a110d7df52892473087392 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 07:04:13 +0100 Subject: Move common gemo/agent map name code into CreateGeom() Fix build break. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 0128cbc..924d7c2 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -334,6 +334,9 @@ namespace OpenSim.Region.Physics.OdePlugin { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + + _parent_scene.geom_name_map[prim_geom] = Name; + _parent_scene.actor_name_map[prim_geom] = this; } if (childPrim) @@ -1510,9 +1513,6 @@ Console.WriteLine("changeadd 1"); } } - _parent_scene.geom_name_map[prim_geom] = Name; - _parent_scene.actor_name_map[prim_geom] = this; - changeSelectedStatus(timestep); m_taintadd = false; @@ -1986,7 +1986,7 @@ Console.WriteLine(" JointCreateFixed"); // Don't need to re-enable body.. it's done in SetMesh if (_parent_scene.needsMeshing(_pbs)) - mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); } CreateGeom(m_targetSpace, mesh); @@ -2007,9 +2007,6 @@ Console.WriteLine(" JointCreateFixed"); d.BodyEnable(Body); } - _parent_scene.geom_name_map[prim_geom] = Name; - _parent_scene.actor_name_map[prim_geom] = this; - changeSelectedStatus(timestamp); if (childPrim) { @@ -2079,7 +2076,7 @@ Console.WriteLine(" JointCreateFixed"); meshlod = _parent_scene.MeshSculptphysicalLOD; // createmesh returns null when it doesn't mesh. - mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); } CreateGeom(m_targetSpace, mesh); @@ -2104,9 +2101,6 @@ Console.WriteLine(" JointCreateFixed"); } } - _parent_scene.geom_name_map[prim_geom] = Name; - _parent_scene.actor_name_map[prim_geom] = this; - changeSelectedStatus(timestamp); if (childPrim) { -- cgit v1.1 From 59f548cda82facef003fb7309180412254a234a1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 1 Aug 2011 23:41:29 +0100 Subject: Get osNpcCreate appearance working with avatars that are currently in the scene. Had to stop using AvatarService for now since it doesn't store baked texture IDs (which is why this was failing). Also failing because cloning appearance was also cloning the AvatarApperance.Owner field, which we weren't then changing. Extended TestCreate() to check this. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 4 ++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++++++-- .../Region/OptionalModules/World/NPC/NPCModule.cs | 25 +++++++++++++++++----- .../World/NPC/Tests/NPCModuleTests.cs | 23 ++++++++++++++++++-- 4 files changed, 52 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 20dff0c..e3e3452 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -151,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (face == null) continue; +// m_log.DebugFormat( +// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", +// face.TextureID, idx, client.Name, client.AgentId); + // if the texture is one of the "defaults" then skip it // this should probably be more intelligent (skirt texture doesnt matter // if the avatar isnt wearing a skirt) but if any of the main baked diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 83b761c..1e121d9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2647,7 +2647,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendAppearanceToAgent(ScenePresence avatar) { -// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); +// m_log.DebugFormat( +// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); avatar.ControllingClient.SendAppearance( m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); @@ -2659,7 +2660,11 @@ namespace OpenSim.Region.Framework.Scenes public AvatarAppearance Appearance { get { return m_appearance; } - set { m_appearance = value; } + set + { + m_appearance = value; +// m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value); + } } #endregion diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 3cdd06d..64f82c9 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -59,14 +59,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC if (m_appearanceCache.ContainsKey(target)) return m_appearanceCache[target]; - AvatarAppearance appearance = scene.AvatarService.GetAppearance(target); - if (appearance != null) + ScenePresence originalPresence = scene.GetScenePresence(target); + + if (originalPresence != null) { - m_appearanceCache.Add(target, appearance); - return appearance; + AvatarAppearance originalAppearance = originalPresence.Appearance; + m_appearanceCache.Add(target, originalAppearance); + return originalAppearance; } + else + { + m_log.DebugFormat( + "[NPC MODULE]: Avatar {0} is not in the scene for us to grab baked textures from them. Using defaults.", target); - return new AvatarAppearance(); + return new AvatarAppearance(); + } } public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) @@ -86,8 +93,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene); AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true); + npcAppearance.Owner = acd.AgentID; acd.Appearance = npcAppearance; +// for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++) +// { +// m_log.DebugFormat( +// "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}", +// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); +// } + scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); scene.AddNewClient(npcAvatar); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 899e721..bc151ed 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -27,11 +27,13 @@ using System; using System.Reflection; +using log4net; using Nini.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Avatar.AvatarFactory; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -58,14 +60,31 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); + AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule(), new LocalAvatarServicesConnector()); + SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule(), new LocalAvatarServicesConnector()); + TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); +// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); + + // 8 is the index of the first baked texture in AvatarAppearance + UUID originalFace8TextureId = TestHelper.ParseTail(0x10); + Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); + Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); + originalTef.TextureID = originalFace8TextureId; + + // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell + // ScenePresence.SendInitialData() to reset our entire appearance. + scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); + + afm.SetAppearance(originalClient, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface(); - UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, UUID.Zero); + UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); ScenePresence npc = scene.GetScenePresence(npcId); + Assert.That(npc, Is.Not.Null); + Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); } } } \ No newline at end of file -- cgit v1.1 From b6ac1c46cd473b129b70344f0001f1e8f97d8860 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 2 Aug 2011 00:13:04 +0100 Subject: Get rid of AvatarAppearance.Owner to simplify the code. This is not used for anything - appearances are always properties of objects with ids (ScenePresence, AgentCircuitData) and just has the potential to get out of sync when the appearance is cloned. --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++-- .../OptionalModules/Framework/Monitoring/MonitorServicesModule.cs | 2 +- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b84c3d5..b3b6cbc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3079,7 +3079,7 @@ namespace OpenSim.Region.Framework.Scenes if (aCircuit == null) { m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance."); - appearance = new AvatarAppearance(client.AgentId); + appearance = new AvatarAppearance(); return; } @@ -3087,7 +3087,7 @@ namespace OpenSim.Region.Framework.Scenes if (appearance == null) { m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName); - appearance = new AvatarAppearance(client.AgentId); + appearance = new AvatarAppearance(); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1e121d9..4739f5b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -916,7 +916,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); // emergency; this really shouldn't happen - m_appearance = new AvatarAppearance(UUID); + m_appearance = new AvatarAppearance(); } AddToPhysicalScene(isFlying); @@ -2651,7 +2651,7 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); avatar.ControllingClient.SendAppearance( - m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); + UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); } // Because appearance setting is in a module, we actually need diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs index d49face..a25e034 100644 --- a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.Framework.Monitoring { protected Scene m_scene; - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public string Name { get { return "Services Health Monitoring Module"; } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 64f82c9..6286dc8 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -93,7 +93,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene); AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true); - npcAppearance.Owner = acd.AgentID; acd.Appearance = npcAppearance; // for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++) -- cgit v1.1 From 17e9d61f4383627434b7b8249cea1a487f001099 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 2 Aug 2011 00:52:48 +0100 Subject: Change GridService.GetRegionByName() to only return info if there is an exact region name match, unlike GetRegionsByName() This should fix the first part of http://opensimulator.org/mantis/view.php?id=5606, and maybe 5605. Thanks to Melanie for helping with this. --- .../ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs index c044407..cd7d6bc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs @@ -64,10 +64,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests } /// - /// Test saving a V0.2 OpenSim Region Archive. + /// Test region registration. /// [Test] - public void TestRegisterRegionV0_2() + public void TestRegisterRegion() { SetUp(); @@ -123,6 +123,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests m_LocalConnector.RegisterRegion(UUID.Zero, r1); GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test"); + Assert.IsNull(result, "Retrieved GetRegionByName \"Test\" is not null"); + + result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test Region 1"); Assert.IsNotNull(result, "Retrieved GetRegionByName is null"); Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match"); -- cgit v1.1 From d2220da2058b9fc7136a5dda588ebc39d77f8531 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 2 Aug 2011 00:58:08 +0100 Subject: remove ancient late 2008 cruft that handles the situation where the GetRegionsByName used to not be implemented/returned null. It's impossible that anybody is still running this since the infrastructure has changed massively since that time. --- OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 2e3b21f..3804017 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -96,16 +96,7 @@ m_log.DebugFormat("MAP NAME=({0})", mapName); // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); - if (regionInfos == null) - { - m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); - // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region - regionInfos = new List(); - GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName); - if (info != null) - regionInfos.Add(info); - } - else if (regionInfos.Count == 0) + if (regionInfos.Count == 0) remoteClient.SendAlertMessage("Hyperlink could not be established."); m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); -- cgit v1.1 From c122489e0947300753281e88771b7a74d49869c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 2 Aug 2011 23:41:12 +0100 Subject: Partially fix autopilot/go here This now works again except that it requires a click or avatar mvmt to get going This is because the ScenePresence.HandleAgentUpdate() method doesn't trigger until the client does something significant, at which point autopilot takes over. Even clicking is enough to trigger. This will be improved presently. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 79 +++++++-------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 11 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 112 ++++++++++----------- OpenSim/Region/Framework/Scenes/UndoState.cs | 2 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 1 + .../Region/OptionalModules/World/NPC/NPCModule.cs | 11 +- 6 files changed, 98 insertions(+), 118 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 60f0075..bb491a1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5266,6 +5266,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); + + AddGenericPacketHandler("autopilot", HandleAutopilot); } #region Packet Handlers @@ -5308,7 +5310,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP ); } else + { update = true; + } // These should be ordered from most-likely to // least likely to change. I've made an initial @@ -5316,6 +5320,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (update) { +// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); + AgentUpdateArgs arg = new AgentUpdateArgs(); arg.AgentID = x.AgentID; arg.BodyRotation = x.BodyRotation; @@ -11609,54 +11615,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP return false; } - /// - /// Breaks down the genericMessagePacket into specific events - /// - /// - /// - /// - public void DecipherGenericMessage(string gmMethod, UUID gmInvoice, GenericMessagePacket.ParamListBlock[] gmParams) + protected void HandleAutopilot(Object sender, string method, List args) { - switch (gmMethod) + try { - case "autopilot": - float locx; - float locy; - float locz; - - try - { - uint regionX; - uint regionY; - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(Utils.BytesToString(gmParams[0].Parameter)) - regionX; - locy = Convert.ToSingle(Utils.BytesToString(gmParams[1].Parameter)) - regionY; - locz = Convert.ToSingle(Utils.BytesToString(gmParams[2].Parameter)); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } - - UpdateVector handlerAutoPilotGo = OnAutoPilotGo; - if (handlerAutoPilotGo != null) - { - handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); - } - m_log.InfoFormat("[CLIENT]: Client Requests autopilot to position <{0},{1},{2}>", locx, locy, locz); - - - break; - default: - m_log.Debug("[CLIENT]: Unknown Generic Message, Method: " + gmMethod + ". Invoice: " + gmInvoice + ". Dumping Params:"); - for (int hi = 0; hi < gmParams.Length; hi++) - { - Console.WriteLine(gmParams[hi].ToString()); - } - //gmpack.MethodData. - break; + float locx = 0f; + float locy = 0f; + float locz = 0f; + uint regionX = 0; + uint regionY = 0; + try + { + Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); + locx = Convert.ToSingle(args[0]) - (float)regionX; + locy = Convert.ToSingle(args[1]) - (float)regionY; + locz = Convert.ToSingle(args[2]); + } + catch (InvalidCastException) + { + m_log.Error("[CLIENT]: Invalid autopilot request"); + return; + } + UpdateVector handlerAutoPilotGo = OnAutoPilotGo; + if (handlerAutoPilotGo != null) + { + handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); + } + } + catch (Exception e) + { + m_log.ErrorFormat("[LLCLIENTVIEW]: HandleAutopilot exception {0} {1}", e.Message, e.StackTrace); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b6fb5a4..1417efb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1650,16 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); if (avatar != null) { - List coords = new List(); - uint regionX = 0; - uint regionY = 0; - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - target.X += regionX; - target.Y += regionY; - coords.Add(target.X.ToString()); - coords.Add(target.Y.ToString()); - coords.Add(target.Z.ToString()); - avatar.DoMoveToPosition(avatar, "", coords); + avatar.DoMoveToPosition(0, target, null); } } else diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4739f5b..a508813 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -116,7 +116,7 @@ namespace OpenSim.Region.Framework.Scenes private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; private bool MouseDown = false; - private SceneObjectGroup proxyObjectGroup; +// private SceneObjectGroup proxyObjectGroup; //private SceneObjectPart proxyObjectPart = null; public Vector3 lastKnownAllowedPosition; public bool sentMessageAboutRestrictedParcelFlyingDown; @@ -779,8 +779,7 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.OnStartAnim += HandleStartAnim; m_controllingClient.OnStopAnim += HandleStopAnim; m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; - m_controllingClient.OnAutoPilotGo += DoAutoPilot; - m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); + m_controllingClient.OnAutoPilotGo += DoMoveToPosition; // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); @@ -1480,6 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes bAllowUpdateMoveToPosition = true; } } + i++; } @@ -1492,12 +1492,21 @@ namespace OpenSim.Region.Framework.Scenes bAllowUpdateMoveToPosition = false; } + m_log.DebugFormat( + "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", + bAllowUpdateMoveToPosition, m_moveToPositionInProgress, m_autopilotMoving); + if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) { - //Check the error term of the current position in relation to the target position - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) + double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); + + // Check the error term of the current position in relation to the target position + if (distanceToTarget <= 1) { - // we are close enough to the target + // We are close enough to the target m_moveToPositionTarget = Vector3.Zero; m_moveToPositionInProgress = false; update_movementflag = true; @@ -1608,8 +1617,6 @@ namespace OpenSim.Region.Framework.Scenes // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); AddNewMovement(agent_control_v3, q); - - } } @@ -1621,61 +1628,44 @@ namespace OpenSim.Region.Framework.Scenes m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } - public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) - { - m_autopilotMoving = true; - m_autoPilotTarget = Pos; - m_sitAtAutoTarget = false; - PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; +// public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) +// { +// m_autopilotMoving = true; +// m_autoPilotTarget = Pos; +// m_sitAtAutoTarget = false; +// PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; +// //proxy.PCode = (byte)PCode.ParticleSystem; +// +// proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); +// proxyObjectGroup.AttachToScene(m_scene); +// +// // Commented out this code since it could never have executed, but might still be informative. +//// if (proxyObjectGroup != null) +//// { +// proxyObjectGroup.SendGroupFullUpdate(); +// remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); +// m_scene.DeleteSceneObject(proxyObjectGroup, false); +//// } +//// else +//// { +//// m_autopilotMoving = false; +//// m_autoPilotTarget = Vector3.Zero; +//// ControllingClient.SendAlertMessage("Autopilot cancelled"); +//// } +// } - proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); - proxyObjectGroup.AttachToScene(m_scene); - - // Commented out this code since it could never have executed, but might still be informative. -// if (proxyObjectGroup != null) -// { - proxyObjectGroup.SendGroupFullUpdate(); - remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - m_scene.DeleteSceneObject(proxyObjectGroup, false); -// } -// else -// { -// m_autopilotMoving = false; -// m_autoPilotTarget = Vector3.Zero; -// ControllingClient.SendAlertMessage("Autopilot cancelled"); -// } - } - - public void DoMoveToPosition(Object sender, string method, List args) + /// + /// Move this presence to the given position over time. + /// + /// + public void DoMoveToPosition(uint not_used, Vector3 pos, IClientAPI remote_client) { - try - { - float locx = 0f; - float locy = 0f; - float locz = 0f; - uint regionX = 0; - uint regionY = 0; - try - { - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(args[0]) - (float)regionX; - locy = Convert.ToSingle(args[1]) - (float)regionY; - locz = Convert.ToSingle(args[2]); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } - m_moveToPositionInProgress = true; - m_moveToPositionTarget = new Vector3(locx, locy, locz); - } - catch (Exception ex) - { - //Why did I get this error? - m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); - } + m_log.DebugFormat( + "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", + Name, pos, m_scene.RegionInfo.RegionName); + + m_moveToPositionInProgress = true; + m_moveToPositionTarget = pos; } private void CheckAtSitTarget() diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 393f42d..d34d8e5 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Scenes { public class UndoState { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 3afcc8d..e87993a 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -99,6 +99,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 6286dc8..8cb8318 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -140,7 +140,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC { ScenePresence sp; scene.TryGetScenePresence(agentID, out sp); - sp.DoAutoPilot(0, pos, m_avatars[agentID]); + +// m_log.DebugFormat( +// "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); +// +// List targetArgs = new List(); +// targetArgs.Add(pos.X); +// targetArgs.Add(pos.Y); +// targetArgs.Add(pos.Z); +// sp.DoMoveToPosition(null, "NPC", targetArgs); +// sp.DoMoveToPosition(0, pos, m_avatars[agentID]); } } } -- cgit v1.1 From 74b23210a7780b2b1e3cb4a7ccf562fe2a8ec25e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 1 Aug 2011 23:14:20 -0700 Subject: Fix Flotsam cache so it will use the disk cache if the memory cache is enabled --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 84fe506..da39202 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -419,7 +419,7 @@ namespace Flotsam.RegionModules.AssetCache if (m_MemoryCacheEnabled) asset = GetFromMemoryCache(id); - else if (m_FileCacheEnabled) + if (asset == null && m_FileCacheEnabled) asset = GetFromFileCache(id); if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) @@ -938,4 +938,4 @@ namespace Flotsam.RegionModules.AssetCache #endregion } -} \ No newline at end of file +} -- cgit v1.1 From f9689f5cc96a937ba592487102e3a04535ca4739 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 00:46:46 +0100 Subject: refactor: move out code from HandleAgentUpdate() which processes updates to move to a set position Also comment out the really spammy log message I accidentally left in on the last commit. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 214 ++++++++++++----------- 1 file changed, 116 insertions(+), 98 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a508813..06b27ca 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1483,105 +1483,8 @@ namespace OpenSim.Region.Framework.Scenes i++; } - //Paupaw:Do Proper PID for Autopilot here - if (bResetMoveToPosition) - { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; + if (DoMoveToPositionUpdate(ref agent_control_v3, bodyRotation, bResetMoveToPosition, bAllowUpdateMoveToPosition)) update_movementflag = true; - bAllowUpdateMoveToPosition = false; - } - - m_log.DebugFormat( - "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", - bAllowUpdateMoveToPosition, m_moveToPositionInProgress, m_autopilotMoving); - - if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) - { - double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget); -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", -// Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); - - // Check the error term of the current position in relation to the target position - if (distanceToTarget <= 1) - { - // We are close enough to the target - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - } - else - { - try - { - // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - Vector3 LocalVectorToTarget3D = - (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords - // Ignore z component of vector - Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget2D.Normalize(); - agent_control_v3 += LocalVectorToTarget2D; - - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // - - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - if (LocalVectorToTarget2D.Y > 0)//MoveLeft - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - //AgentControlFlags - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.Y < 0) //MoveRight - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - update_movementflag = true; - } - if (LocalVectorToTarget2D.X < 0) //MoveBack - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.X > 0) //Move Forward - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - update_movementflag = true; - } - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } - } - } } // Cause the avatar to stop flying if it's colliding @@ -1628,6 +1531,121 @@ namespace OpenSim.Region.Framework.Scenes m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } + /// + /// Process moving the avatar if a position has been set. + /// + /// Cumulative agent movement that this method will update. + /// New body rotation of the avatar. + /// If true, clear the move to position + /// If true, allow the update in principle. + /// True if movement has been updated in some way. False otherwise. + protected bool DoMoveToPositionUpdate( + ref Vector3 agent_control_v3, Quaternion bodyRotation, bool reset, bool allowUpdate) + { + bool updated = false; + + //Paupaw:Do Proper PID for Autopilot here + if (reset) + { + m_moveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + updated = true; + } + + m_log.DebugFormat( + "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", + allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); + + if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) + { + double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); + + // Check the error term of the current position in relation to the target position + if (distanceToTarget <= 1) + { + // We are close enough to the target + m_moveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + updated = true; + } + else + { + try + { + // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. + // This movement vector gets added to the velocity through AddNewMovement(). + // Theoretically we might need a more complex PID approach here if other + // unknown forces are acting on the avatar and we need to adaptively respond + // to such forces, but the following simple approach seems to works fine. + Vector3 LocalVectorToTarget3D = + (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords + * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords + // Ignore z component of vector + Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); + LocalVectorToTarget2D.Normalize(); + agent_control_v3 += LocalVectorToTarget2D; + + // update avatar movement flags. the avatar coordinate system is as follows: + // + // +X (forward) + // + // ^ + // | + // | + // | + // | + // (left) +Y <--------o--------> -Y + // avatar + // | + // | + // | + // | + // v + // -X + // + + // based on the above avatar coordinate system, classify the movement into + // one of left/right/back/forward. + if (LocalVectorToTarget2D.Y > 0)//MoveLeft + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + //AgentControlFlags + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + updated = true; + } + else if (LocalVectorToTarget2D.Y < 0) //MoveRight + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + updated = true; + } + if (LocalVectorToTarget2D.X < 0) //MoveBack + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + updated = true; + } + else if (LocalVectorToTarget2D.X > 0) //Move Forward + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + updated = true; + } + } + catch (Exception e) + { + //Avoid system crash, can be slower but... + m_log.DebugFormat("Crash! {0}", e.ToString()); + } + } + } + + return updated; + } + // public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) // { // m_autopilotMoving = true; -- cgit v1.1 From 1c126e6e222989dc9ce66e65380d120c7ee8d24d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 00:55:52 +0100 Subject: refactor: Move update_movement_flag and the final check inside the m_allowMovement if in HandleAgentUpdate() since it's logically only ever used there --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 06b27ca..7cc6d66 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1377,11 +1377,11 @@ namespace OpenSim.Region.Framework.Scenes { return; } - - bool update_movementflag = false; if (m_allowMovement && !SitGround) { + bool update_movementflag = false; + if (agentData.UseClientAgentPosition) { m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; @@ -1521,10 +1521,10 @@ namespace OpenSim.Region.Framework.Scenes AddNewMovement(agent_control_v3, q); } - } - if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) - Animator.UpdateMovementAnimations(); + if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) + Animator.UpdateMovementAnimations(); + } m_scene.EventManager.TriggerOnClientMovement(this); -- cgit v1.1 From 0c23764ce2f7fd8b697ff493bf50742b9aaf2a6a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 01:12:32 +0100 Subject: get autopilot/go here to work immediately. This works with viewer 1.23.5 and so in theory should work with libopenmetaverse. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7cc6d66..9c71492 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1552,9 +1552,9 @@ namespace OpenSim.Region.Framework.Scenes updated = true; } - m_log.DebugFormat( - "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", - allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", +// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) { @@ -1684,6 +1684,10 @@ namespace OpenSim.Region.Framework.Scenes m_moveToPositionInProgress = true; m_moveToPositionTarget = pos; + + Vector3 agent_control_v3 = new Vector3(); + DoMoveToPositionUpdate(ref agent_control_v3, Rotation, false, true); + AddNewMovement(agent_control_v3, Rotation); } private void CheckAtSitTarget() -- cgit v1.1 From 30e816bfa2fe3145a43723dfea6c4765551f5e04 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 02:04:38 +0100 Subject: Implement move to/autopilot for z axis movement as well. This is jerky (an artifact of the way it's being done, I think), but it's better than on implementation. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 4 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 53 ++++++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 4865481..1334230 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -295,7 +295,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (move.X != 0f || move.Y != 0f) { // Walking / crouchwalking / running - if (move.Z < 0f) + if (move.Z < 0) return "CROUCHWALK"; else if (m_scenePresence.SetAlwaysRun) return "RUN"; @@ -305,7 +305,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation else { // Not walking - if (move.Z < 0f) + if (move.Z < 0) return "CROUCH"; else return "STAND"; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9c71492..7b228c6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1559,9 +1559,9 @@ namespace OpenSim.Region.Framework.Scenes if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) { double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget); -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", -// Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); + m_log.DebugFormat( + "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", + Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position if (distanceToTarget <= 1) @@ -1575,7 +1575,7 @@ namespace OpenSim.Region.Framework.Scenes { try { - // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. + // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. // This movement vector gets added to the velocity through AddNewMovement(). // Theoretically we might need a more complex PID approach here if other // unknown forces are acting on the avatar and we need to adaptively respond @@ -1584,9 +1584,8 @@ namespace OpenSim.Region.Framework.Scenes (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords // Ignore z component of vector - Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget2D.Normalize(); - agent_control_v3 += LocalVectorToTarget2D; +// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); + LocalVectorToTarget3D.Normalize(); // update avatar movement flags. the avatar coordinate system is as follows: // @@ -1609,31 +1608,48 @@ namespace OpenSim.Region.Framework.Scenes // based on the above avatar coordinate system, classify the movement into // one of left/right/back/forward. - if (LocalVectorToTarget2D.Y > 0)//MoveLeft + if (LocalVectorToTarget3D.X < 0) //MoveBack + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + updated = true; + } + else if (LocalVectorToTarget3D.X > 0) //Move Forward + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + updated = true; + } + + if (LocalVectorToTarget3D.Y > 0) //MoveLeft { m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; //AgentControlFlags AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; updated = true; } - else if (LocalVectorToTarget2D.Y < 0) //MoveRight + else if (LocalVectorToTarget3D.Y < 0) //MoveRight { m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; updated = true; } - if (LocalVectorToTarget2D.X < 0) //MoveBack + + if (LocalVectorToTarget3D.Z > 0) //Up { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + //AgentControlFlags + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; updated = true; } - else if (LocalVectorToTarget2D.X > 0) //Move Forward + else if (LocalVectorToTarget3D.Z < 0) //Down { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; updated = true; } + + agent_control_v3 += LocalVectorToTarget3D; } catch (Exception e) { @@ -1682,6 +1698,13 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", Name, pos, m_scene.RegionInfo.RegionName); + Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2); + pos += heightAdjust; + + // Anti duck-walking measure + if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f) + pos.Z = AbsolutePosition.Z; + m_moveToPositionInProgress = true; m_moveToPositionTarget = pos; -- cgit v1.1 From 68a5fe04318fed4b306e8405861203c19a313a2f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 02:59:49 +0100 Subject: Improve z axis move to/autopilot so the avatar does alternative crouch/huzzah when walking along the ground Moving a flying avatar to a ground point doesn't yet land the avatar. This may or may not be the best thing --- .../Scenes/Animation/ScenePresenceAnimator.cs | 8 ++++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 34 +++++++++++++++------- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 1334230..4ab818f 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -40,6 +42,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public class ScenePresenceAnimator { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public AnimationSet Animations { get { return m_animations; } @@ -262,7 +266,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_animTickFall = 0; - if (move.Z > 0f) + if (move.Z > 0.2f) { // Jumping if (!jumping) @@ -323,6 +327,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void UpdateMovementAnimations() { m_movementAnimation = GetMovementAnimation(); +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Got animation {0} for {1}", m_movementAnimation, m_scenePresence.Name); TrySetMovementAnimation(m_movementAnimation); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7b228c6..a610b6b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1522,7 +1522,11 @@ namespace OpenSim.Region.Framework.Scenes AddNewMovement(agent_control_v3, q); } - if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) + if (update_movementflag + && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) + && (m_parentID == 0) + && !SitGround + && !m_moveToPositionInProgress) Animator.UpdateMovementAnimations(); } @@ -1559,9 +1563,9 @@ namespace OpenSim.Region.Framework.Scenes if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) { double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget); - m_log.DebugFormat( - "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", - Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position if (distanceToTarget <= 1) @@ -1637,15 +1641,15 @@ namespace OpenSim.Region.Framework.Scenes if (LocalVectorToTarget3D.Z > 0) //Up { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; //AgentControlFlags - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; updated = true; } else if (LocalVectorToTarget3D.Z < 0) //Down { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; updated = true; } @@ -1694,16 +1698,24 @@ namespace OpenSim.Region.Framework.Scenes /// public void DoMoveToPosition(uint not_used, Vector3 pos, IClientAPI remote_client) { - m_log.DebugFormat( - "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", - Name, pos, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", +// Name, pos, m_scene.RegionInfo.RegionName); + + if (pos.X < 0 || pos.X >= Constants.RegionSize + || pos.Y < 0 || pos.Y >= Constants.RegionSize + || pos.Z < 0) + return; Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2); pos += heightAdjust; // Anti duck-walking measure if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f) + { +// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition); pos.Z = AbsolutePosition.Z; + } m_moveToPositionInProgress = true; m_moveToPositionTarget = pos; -- cgit v1.1 From 6e4ec2972266ae250337867fe1ba1944131f212d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 04:19:19 +0100 Subject: Do a partial fix/implementation of OSSL osNpcMoveTo() Avatar moves and stops. However, will stop in mid stride. And if the move to position is in the air, avatar will continue to make vain and quite hilarious attempts to take off (but never doing so). Clearly more work is needed. --- .../CoreModules/World/Land/LandManagementModule.cs | 69 ++++++++++------------ OpenSim/Region/Framework/Scenes/EventManager.cs | 11 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 37 ++++++++---- .../Region/OptionalModules/World/NPC/NPCModule.cs | 59 ++++++++++++++---- 4 files changed, 109 insertions(+), 67 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 63dec15..7554e12 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -470,53 +470,48 @@ namespace OpenSim.Region.CoreModules.World.Land SendLandUpdate(avatar, false); } - public void EventManagerOnSignificantClientMovement(IClientAPI remote_client) + public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar) { - ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); - - if (clientAvatar != null) + SendLandUpdate(clientAvatar); + SendOutNearestBanLine(clientAvatar.ControllingClient); + ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); + if (parcel != null) { - SendLandUpdate(clientAvatar); - SendOutNearestBanLine(remote_client); - ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); - if (parcel != null) + if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && + clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) { - if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) + EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, + m_scene.RegionInfo.RegionID); + //They are going under the safety line! + if (!parcel.IsBannedFromLand(clientAvatar.UUID)) { - EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, - m_scene.RegionInfo.RegionID); - //They are going under the safety line! - if (!parcel.IsBannedFromLand(clientAvatar.UUID)) - { - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; - } + clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; } - else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && - parcel.IsBannedFromLand(clientAvatar.UUID)) + } + else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && + parcel.IsBannedFromLand(clientAvatar.UUID)) + { + //once we've sent the message once, keep going toward the target until we are done + if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) { - //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) - { - SendYouAreBannedNotice(clientAvatar); - ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); - } + SendYouAreBannedNotice(clientAvatar); + ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); } - else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) - { - //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) - { - SendYouAreRestrictedNotice(clientAvatar); - ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); - } - } - else + } + else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) + { + //once we've sent the message once, keep going toward the target until we are done + if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) { - //when we are finally in a safe place, lets release the forced position lock - forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); + SendYouAreRestrictedNotice(clientAvatar); + ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); } } + else + { + //when we are finally in a safe place, lets release the forced position lock + forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); + } } } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index b67937d..96da2c3 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -165,8 +165,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; - public delegate void SignificantClientMovement(IClientAPI remote_client); - public event SignificantClientMovement OnSignificantClientMovement; + public event Action OnSignificantClientMovement; public delegate void IncomingInstantMessage(GridInstantMessage message); public event IncomingInstantMessage OnIncomingInstantMessage; @@ -1592,16 +1591,16 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerSignificantClientMovement(IClientAPI client) + public void TriggerSignificantClientMovement(ScenePresence presence) { - SignificantClientMovement handlerSignificantClientMovement = OnSignificantClientMovement; + Action handlerSignificantClientMovement = OnSignificantClientMovement; if (handlerSignificantClientMovement != null) { - foreach (SignificantClientMovement d in handlerSignificantClientMovement.GetInvocationList()) + foreach (Action d in handlerSignificantClientMovement.GetInvocationList()) { try { - d(client); + d(presence); } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a610b6b..9558258 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -211,7 +211,8 @@ namespace OpenSim.Region.Framework.Scenes //PauPaw:Proper PID Controler for autopilot************ private bool m_moveToPositionInProgress; - private Vector3 m_moveToPositionTarget; + + public Vector3 MoveToPositionTarget { get; private set; } private bool m_followCamAuto; @@ -1385,7 +1386,7 @@ namespace OpenSim.Region.Framework.Scenes if (agentData.UseClientAgentPosition) { m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; - m_moveToPositionTarget = agentData.ClientAgentPosition; + MoveToPositionTarget = agentData.ClientAgentPosition; } int i = 0; @@ -1543,16 +1544,17 @@ namespace OpenSim.Region.Framework.Scenes /// If true, clear the move to position /// If true, allow the update in principle. /// True if movement has been updated in some way. False otherwise. - protected bool DoMoveToPositionUpdate( + public bool DoMoveToPositionUpdate( ref Vector3 agent_control_v3, Quaternion bodyRotation, bool reset, bool allowUpdate) { +// m_log.DebugFormat("[SCENE PRESENCE]: Called DoMoveToPositionUpdate() for {0}", Name); + bool updated = false; //Paupaw:Do Proper PID for Autopilot here if (reset) { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; + ResetMoveToPosition(); updated = true; } @@ -1562,16 +1564,16 @@ namespace OpenSim.Region.Framework.Scenes if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) { - double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget); -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", -// Name, AbsolutePosition, m_moveToPositionTarget, distanceToTarget); + double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); + m_log.DebugFormat( + "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", + Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position if (distanceToTarget <= 1) { // We are close enough to the target - m_moveToPositionTarget = Vector3.Zero; + MoveToPositionTarget = Vector3.Zero; m_moveToPositionInProgress = false; updated = true; } @@ -1585,7 +1587,7 @@ namespace OpenSim.Region.Framework.Scenes // unknown forces are acting on the avatar and we need to adaptively respond // to such forces, but the following simple approach seems to works fine. Vector3 LocalVectorToTarget3D = - (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords + (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords // Ignore z component of vector // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); @@ -1718,13 +1720,22 @@ namespace OpenSim.Region.Framework.Scenes } m_moveToPositionInProgress = true; - m_moveToPositionTarget = pos; + MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); DoMoveToPositionUpdate(ref agent_control_v3, Rotation, false, true); AddNewMovement(agent_control_v3, Rotation); } + /// + /// Reset the move to position. + /// + public void ResetMoveToPosition() + { + MoveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + } + private void CheckAtSitTarget() { //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); @@ -2731,7 +2742,7 @@ namespace OpenSim.Region.Framework.Scenes if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = AbsolutePosition; - m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); + m_scene.EventManager.TriggerSignificantClientMovement(this); } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 8cb8318..fcfacc6 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -46,12 +46,54 @@ namespace OpenSim.Region.OptionalModules.World.NPC // private const bool m_enabled = false; - private Dictionary m_avatars = new Dictionary(); - private Dictionary m_appearanceCache = new Dictionary(); + private Dictionary m_avatars = new Dictionary(); + private Dictionary m_appearanceCache = new Dictionary(); public void Initialise(Scene scene, IConfigSource source) { scene.RegisterModuleInterface(this); + scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; + } + + public void HandleOnSignificantClientMovement(ScenePresence presence) + { + lock (m_avatars) + { + if (m_avatars.ContainsKey(presence.UUID)) + { + double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget); +// m_log.DebugFormat( +// "[NPC MODULE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); + + // Check the error term of the current position in relation to the target position + if (distanceToTarget <= 1) + { +// m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0} {1}", presence.Name, presence.UUID); + // We are close enough to the target for now + presence.ResetMoveToPosition(); + presence.Velocity = Vector3.Zero; + + // FIXME: This doesn't work + if (presence.PhysicsActor.Flying) + presence.Animator.TrySetMovementAnimation("HOVER"); + else + presence.Animator.TrySetMovementAnimation("STAND"); + } + else + { + Vector3 agent_control_v3 = new Vector3(); + presence.DoMoveToPositionUpdate(ref agent_control_v3, presence.Rotation, false, true); + presence.AddNewMovement(agent_control_v3, presence.Rotation); + } +// +//// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null); + +// +// + + } + } } private AvatarAppearance GetAppearance(UUID target, Scene scene) @@ -141,15 +183,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC ScenePresence sp; scene.TryGetScenePresence(agentID, out sp); -// m_log.DebugFormat( -// "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); -// -// List targetArgs = new List(); -// targetArgs.Add(pos.X); -// targetArgs.Add(pos.Y); -// targetArgs.Add(pos.Z); -// sp.DoMoveToPosition(null, "NPC", targetArgs); -// sp.DoMoveToPosition(0, pos, m_avatars[agentID]); + m_log.DebugFormat( + "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); + + sp.DoMoveToPosition(0, pos, m_avatars[agentID]); } } } -- cgit v1.1 From 797def8aa4a009ba3bc44d6b73e063e4bb61ba97 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 04:33:45 +0100 Subject: Put config to enable disable [NPC] module. Default is disabled. You will need to explicitly enable to toy with this. --- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index fcfacc6..d139b25 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -44,15 +44,18 @@ namespace OpenSim.Region.OptionalModules.World.NPC { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // private const bool m_enabled = false; - private Dictionary m_avatars = new Dictionary(); private Dictionary m_appearanceCache = new Dictionary(); public void Initialise(Scene scene, IConfigSource source) { - scene.RegisterModuleInterface(this); - scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; + IConfig config = source.Configs["NPC"]; + + if (config != null && config.GetBoolean("Enabled", false)) + { + scene.RegisterModuleInterface(this); + scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; + } } public void HandleOnSignificantClientMovement(ScenePresence presence) -- cgit v1.1 From b7a3f36c65474ffd959ff0053f1602235ce2f2e0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 04:48:47 +0100 Subject: enable the NPC module for its regression test --- OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index bc151ed..9e77e7d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -59,6 +59,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests config.AddConfig("AvatarService"); config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); + config.AddConfig("NPC"); + config.Configs["NPC"].Set("Enabled", "true"); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneSetupHelpers.SetupScene(); -- cgit v1.1 From 2964467708871f5932c46ad04e002a5506dd7732 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 22:11:05 +0100 Subject: get rid of vestigal move to parameters --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 44 +++++++--------------- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 +++- .../Server/IRCClientView.cs | 2 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 7 files changed, 24 insertions(+), 37 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index bb491a1..4a36b5d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; @@ -11617,36 +11617,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected void HandleAutopilot(Object sender, string method, List args) { - try - { - float locx = 0f; - float locy = 0f; - float locz = 0f; - uint regionX = 0; - uint regionY = 0; - try - { - Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(args[0]) - (float)regionX; - locy = Convert.ToSingle(args[1]) - (float)regionY; - locz = Convert.ToSingle(args[2]); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } + float locx = 0; + float locy = 0; + float locz = 0; + uint regionX = 0; + uint regionY = 0; - UpdateVector handlerAutoPilotGo = OnAutoPilotGo; - if (handlerAutoPilotGo != null) - { - handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); - } - } - catch (Exception e) - { - m_log.ErrorFormat("[LLCLIENTVIEW]: HandleAutopilot exception {0} {1}", e.Message, e.StackTrace); - } + Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); + locx = Convert.ToSingle(args[0]) - (float)regionX; + locy = Convert.ToSingle(args[1]) - (float)regionY; + locz = Convert.ToSingle(args[2]); + + Action handlerAutoPilotGo = OnAutoPilotGo; + if (handlerAutoPilotGo != null) + handlerAutoPilotGo(new Vector3(locx, locy, locz)); } /// diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 17766ea..4f58ab0 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1417efb..1370afc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1650,7 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); if (avatar != null) { - avatar.DoMoveToPosition(0, target, null); + avatar.DoMoveToPosition(target); } } else diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9558258..19b7f19 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1537,8 +1537,11 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Process moving the avatar if a position has been set. + /// Process move to update for an avatar. /// + /// + /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3 + /// /// Cumulative agent movement that this method will update. /// New body rotation of the avatar. /// If true, clear the move to position @@ -1698,7 +1701,7 @@ namespace OpenSim.Region.Framework.Scenes /// Move this presence to the given position over time. /// /// - public void DoMoveToPosition(uint not_used, Vector3 pos, IClientAPI remote_client) + public void DoMoveToPosition(Vector3 pos) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 3335f2e..a0c1ab1 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index e87993a..dfc624d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index d139b25..a78ad0c 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -189,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_log.DebugFormat( "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); - sp.DoMoveToPosition(0, pos, m_avatars[agentID]); + sp.DoMoveToPosition(pos); } } } -- cgit v1.1 From a333c60f28acf1298c929f9129d3537f3f97e638 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 22:34:05 +0100 Subject: refactor: rename the move to position methods to move to target to be consistent with terminology used by scene object part and elsewhere --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 46 ++++++---------------- .../Region/OptionalModules/World/NPC/NPCModule.cs | 6 +-- 3 files changed, 15 insertions(+), 39 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1370afc..57baa99 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1650,7 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); if (avatar != null) { - avatar.DoMoveToPosition(target); + avatar.MoveToTarget(target); } } else diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 19b7f19..f482974 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -780,7 +780,7 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.OnStartAnim += HandleStartAnim; m_controllingClient.OnStopAnim += HandleStopAnim; m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; - m_controllingClient.OnAutoPilotGo += DoMoveToPosition; + m_controllingClient.OnAutoPilotGo += MoveToTarget; // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); @@ -1484,7 +1484,7 @@ namespace OpenSim.Region.Framework.Scenes i++; } - if (DoMoveToPositionUpdate(ref agent_control_v3, bodyRotation, bResetMoveToPosition, bAllowUpdateMoveToPosition)) + if (HandleMoveToPositionUpdate(ref agent_control_v3, bodyRotation, bResetMoveToPosition, bAllowUpdateMoveToPosition)) update_movementflag = true; } @@ -1547,7 +1547,7 @@ namespace OpenSim.Region.Framework.Scenes /// If true, clear the move to position /// If true, allow the update in principle. /// True if movement has been updated in some way. False otherwise. - public bool DoMoveToPositionUpdate( + public bool HandleMoveToPositionUpdate( ref Vector3 agent_control_v3, Quaternion bodyRotation, bool reset, bool allowUpdate) { // m_log.DebugFormat("[SCENE PRESENCE]: Called DoMoveToPositionUpdate() for {0}", Name); @@ -1557,7 +1557,7 @@ namespace OpenSim.Region.Framework.Scenes //Paupaw:Do Proper PID for Autopilot here if (reset) { - ResetMoveToPosition(); + ResetMoveToTarget(); updated = true; } @@ -1646,6 +1646,8 @@ namespace OpenSim.Region.Framework.Scenes if (LocalVectorToTarget3D.Z > 0) //Up { + // Don't set these flags for up or down - doing so will make the avatar crouch or + // keep trying to jump even if walking along level ground //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; //AgentControlFlags //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; @@ -1671,37 +1673,11 @@ namespace OpenSim.Region.Framework.Scenes return updated; } -// public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) -// { -// m_autopilotMoving = true; -// m_autoPilotTarget = Pos; -// m_sitAtAutoTarget = false; -// PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; -// //proxy.PCode = (byte)PCode.ParticleSystem; -// -// proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); -// proxyObjectGroup.AttachToScene(m_scene); -// -// // Commented out this code since it could never have executed, but might still be informative. -//// if (proxyObjectGroup != null) -//// { -// proxyObjectGroup.SendGroupFullUpdate(); -// remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); -// m_scene.DeleteSceneObject(proxyObjectGroup, false); -//// } -//// else -//// { -//// m_autopilotMoving = false; -//// m_autoPilotTarget = Vector3.Zero; -//// ControllingClient.SendAlertMessage("Autopilot cancelled"); -//// } -// } - /// - /// Move this presence to the given position over time. + /// Move to the given target over time. /// /// - public void DoMoveToPosition(Vector3 pos) + public void MoveToTarget(Vector3 pos) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", @@ -1726,14 +1702,14 @@ namespace OpenSim.Region.Framework.Scenes MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); - DoMoveToPositionUpdate(ref agent_control_v3, Rotation, false, true); + HandleMoveToPositionUpdate(ref agent_control_v3, Rotation, false, true); AddNewMovement(agent_control_v3, Rotation); } /// - /// Reset the move to position. + /// Reset the move to target. /// - public void ResetMoveToPosition() + public void ResetMoveToTarget() { MoveToPositionTarget = Vector3.Zero; m_moveToPositionInProgress = false; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index a78ad0c..1d88e43 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -74,7 +74,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { // m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0} {1}", presence.Name, presence.UUID); // We are close enough to the target for now - presence.ResetMoveToPosition(); + presence.ResetMoveToTarget(); presence.Velocity = Vector3.Zero; // FIXME: This doesn't work @@ -86,7 +86,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC else { Vector3 agent_control_v3 = new Vector3(); - presence.DoMoveToPositionUpdate(ref agent_control_v3, presence.Rotation, false, true); + presence.HandleMoveToPositionUpdate(ref agent_control_v3, presence.Rotation, false, true); presence.AddNewMovement(agent_control_v3, presence.Rotation); } // @@ -189,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_log.DebugFormat( "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); - sp.DoMoveToPosition(pos); + sp.MoveToTarget(pos); } } } -- cgit v1.1 From e0503d397c8cda2c12944e8a8200e417164a4121 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 22:45:43 +0100 Subject: stop avatar service being set up in NPC TestCreate() - it's no longer used --- .../World/NPC/Tests/NPCModuleTests.cs | 54 +++++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 9e77e7d..c5770d3 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -54,17 +54,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests IConfigSource config = new IniConfigSource(); - config.AddConfig("Modules"); - config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); - config.AddConfig("AvatarService"); - config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); - config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); +// config.AddConfig("Modules"); +// config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); +// config.AddConfig("AvatarService"); +// config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); +// config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); config.AddConfig("NPC"); config.Configs["NPC"].Set("Enabled", "true"); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule(), new LocalAvatarServicesConnector()); + SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); @@ -88,5 +88,47 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc, Is.Not.Null); Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); } + +// [Test] +// public void TestMove() +// { +// TestHelper.InMethod(); +//// log4net.Config.XmlConfigurator.Configure(); +// +// IConfigSource config = new IniConfigSource(); +// +// config.AddConfig("Modules"); +// config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); +// config.AddConfig("AvatarService"); +// config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); +// config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); +// config.AddConfig("NPC"); +// config.Configs["NPC"].Set("Enabled", "true"); +// +// TestScene scene = SceneSetupHelpers.SetupScene(); +// SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule(), new LocalAvatarServicesConnector()); +// TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); +//// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); +// +// // 8 is the index of the first baked texture in AvatarAppearance +// UUID originalFace8TextureId = TestHelper.ParseTail(0x10); +// Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); +// Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); +// originalTef.TextureID = originalFace8TextureId; +// +// // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell +// // ScenePresence.SendInitialData() to reset our entire appearance. +// scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); +// +// afm.SetAppearance(originalClient, originalTe, null); +// +// INPCModule npcModule = scene.RequestModuleInterface(); +// UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); +// +// ScenePresence npc = scene.GetScenePresence(npcId); +// +// Assert.That(npc, Is.Not.Null); +// Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); +// } } } \ No newline at end of file -- cgit v1.1 From d78fe441916b6e66cd5c071bcbbf027bb28feabd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 22:51:46 +0100 Subject: Add passing but incomplete NPC move regression test --- .../World/NPC/Tests/NPCModuleTests.cs | 72 ++++++++-------------- 1 file changed, 25 insertions(+), 47 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index c5770d3..46e39ef 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -53,12 +53,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // log4net.Config.XmlConfigurator.Configure(); IConfigSource config = new IniConfigSource(); - -// config.AddConfig("Modules"); -// config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); -// config.AddConfig("AvatarService"); -// config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); -// config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); config.AddConfig("NPC"); config.Configs["NPC"].Set("Enabled", "true"); @@ -89,46 +83,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); } -// [Test] -// public void TestMove() -// { -// TestHelper.InMethod(); -//// log4net.Config.XmlConfigurator.Configure(); -// -// IConfigSource config = new IniConfigSource(); -// -// config.AddConfig("Modules"); -// config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); -// config.AddConfig("AvatarService"); -// config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); -// config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); -// config.AddConfig("NPC"); -// config.Configs["NPC"].Set("Enabled", "true"); -// -// TestScene scene = SceneSetupHelpers.SetupScene(); -// SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule(), new LocalAvatarServicesConnector()); -// TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); -//// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); -// -// // 8 is the index of the first baked texture in AvatarAppearance -// UUID originalFace8TextureId = TestHelper.ParseTail(0x10); -// Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); -// Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); -// originalTef.TextureID = originalFace8TextureId; -// -// // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell -// // ScenePresence.SendInitialData() to reset our entire appearance. -// scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); -// -// afm.SetAppearance(originalClient, originalTe, null); -// -// INPCModule npcModule = scene.RequestModuleInterface(); -// UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); -// -// ScenePresence npc = scene.GetScenePresence(npcId); -// -// Assert.That(npc, Is.Not.Null); -// Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); -// } + [Test] + public void TestMove() + { + TestHelper.InMethod(); + log4net.Config.XmlConfigurator.Configure(); + + IConfigSource config = new IniConfigSource(); + + config.AddConfig("NPC"); + config.Configs["NPC"].Set("Enabled", "true"); + + TestScene scene = SceneSetupHelpers.SetupScene(); + SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule()); + TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); +// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); + + Vector3 startPos = new Vector3(128, 128, 30); + INPCModule npcModule = scene.RequestModuleInterface(); + UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, originalClient.AgentId); + + ScenePresence npc = scene.GetScenePresence(npcId); + Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + + // Not yet complete + } } } \ No newline at end of file -- cgit v1.1 From 21d8a6b0e8f1480a5ac75ae4e76d01d4ae2fb13f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 23:06:18 +0100 Subject: extend move test to check one beat of the simulator without actually asking the npc to move. --- .../Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 8 +++++++- .../Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs | 12 ++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 46e39ef..4e2b5f1 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -87,7 +87,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests public void TestMove() { TestHelper.InMethod(); - log4net.Config.XmlConfigurator.Configure(); +// log4net.Config.XmlConfigurator.Configure(); IConfigSource config = new IniConfigSource(); @@ -106,6 +106,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests ScenePresence npc = scene.GetScenePresence(npcId); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + // For now, we'll make the scene presence fly to simplify this test, but this needs to change. + npc.PhysicsActor.Flying = true; + + scene.Update(); + Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + // Not yet complete } } diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index 6c9d9ab..1ceed1a 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -123,11 +123,15 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin actorPosition.X = ((int)Constants.RegionSize - 0.1f); } - float height = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + actor.Size.Z; + float terrainHeight = 0; + if (_heightMap != null) + terrainHeight = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X]; + + float height = terrainHeight + actor.Size.Z; + if (actor.Flying) { - if (actor.Position.Z + (actor.Velocity.Z*timeStep) < - _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2) + if (actor.Position.Z + (actor.Velocity.Z * timeStep) < terrainHeight + 2) { actorPosition.Z = height; actorVelocity.Z = 0; @@ -135,7 +139,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin } else { - actorPosition.Z += actor.Velocity.Z*timeStep; + actorPosition.Z += actor.Velocity.Z * timeStep; actor.IsColliding = false; } } -- cgit v1.1 From 31cea17f8e7995277008370738be1d510dfede7a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 23:13:52 +0100 Subject: extend move test to check avatar is moving in the right direction after setting a move target --- .../OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 4e2b5f1..512405a 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -112,6 +112,19 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests scene.Update(); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + Vector3 targetPos = new Vector3(128, 128, 40); + npcModule.Autopilot(npc.UUID, scene, targetPos); + + Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + + scene.Update(); + + // We should really check the exact figure. + Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); + Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); + Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z)); + Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z)); + // Not yet complete } } -- cgit v1.1 From 61d49d4f63eafa68d0b63877029da3475d977263 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 23:20:36 +0100 Subject: rename NPC.Autopilot to NPC.MoveToTarget internally. Add method doc to INPCModule --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 32 +++++++++++++++++++++- .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 2 +- .../Shared/Api/Implementation/OSSL_Api.cs | 2 +- 4 files changed, 34 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 21a755f..fa8d6b6 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -32,9 +32,39 @@ namespace OpenSim.Region.Framework.Interfaces { public interface INPCModule { + /// + /// Create an NPC + /// + /// + /// + /// + /// + /// The UUID of the avatar from which to clone the NPC's appearance from. + /// The UUID of the ScenePresence created. UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); - void Autopilot(UUID agentID, Scene scene, Vector3 pos); + + /// + /// Move an NPC to a target over time. + /// + /// The UUID of the NPC + /// + /// + void MoveToTarget(UUID agentID, Scene scene, Vector3 pos); + + /// + /// Get the NPC to say something. + /// + /// The UUID of the NPC + /// + /// void Say(UUID agentID, Scene scene, string text); + + + /// + /// Delete an NPC. + /// + /// The UUID of the NPC + /// void DeleteNPC(UUID agentID, Scene scene); } } \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 1d88e43..f9c41d7 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -177,7 +177,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC return npcAvatar.AgentId; } - public void Autopilot(UUID agentID, Scene scene, Vector3 pos) + public void MoveToTarget(UUID agentID, Scene scene, Vector3 pos) { lock (m_avatars) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 512405a..2e3d431 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); Vector3 targetPos = new Vector3(128, 128, 40); - npcModule.Autopilot(npc.UUID, scene, targetPos); + npcModule.MoveToTarget(npc.UUID, scene, targetPos); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b710229..8093502 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2110,7 +2110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (module != null) { Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); - module.Autopilot(new UUID(npc.m_string), World, pos); + module.MoveToTarget(new UUID(npc.m_string), World, pos); } } -- cgit v1.1 From 31fb6b2d72081a7ab27199f57e6a40fc1e478bc2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 23:40:05 +0100 Subject: remove move to duck walk compensation - no longer required. extends npc move to regression test to check stop after sufficient sim updates --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 24 +++++++++++----------- .../World/NPC/Tests/NPCModuleTests.cs | 6 +++++- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f482974..6a3e79a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1568,9 +1568,9 @@ namespace OpenSim.Region.Framework.Scenes if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) { double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); - m_log.DebugFormat( - "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", - Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position if (distanceToTarget <= 1) @@ -1688,15 +1688,15 @@ namespace OpenSim.Region.Framework.Scenes || pos.Z < 0) return; - Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2); - pos += heightAdjust; - - // Anti duck-walking measure - if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f) - { -// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition); - pos.Z = AbsolutePosition.Z; - } +// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2); +// pos += heightAdjust; +// +// // Anti duck-walking measure +// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f) +// { +//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition); +// pos.Z = AbsolutePosition.Z; +// } m_moveToPositionInProgress = true; MoveToPositionTarget = pos; diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 2e3d431..57847f7 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -125,7 +125,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z)); Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z)); - // Not yet complete + for (int i = 0; i < 10; i++) + scene.Update(); + + double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); + Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position"); } } } \ No newline at end of file -- cgit v1.1 From 6ab01b338f3888d84bdb710bc7e8cae1899beb8d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Aug 2011 23:59:13 +0100 Subject: Stop calling the SP.ResetMoveToTarget() code if a target is not actually set --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6a3e79a..71dd2eb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1430,6 +1430,7 @@ namespace OpenSim.Region.Framework.Scenes // The fact that m_movementflag is a byte needs to be fixed // it really should be a uint + // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. uint nudgehack = 250; foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) { @@ -1554,11 +1555,15 @@ namespace OpenSim.Region.Framework.Scenes bool updated = false; - //Paupaw:Do Proper PID for Autopilot here if (reset) { - ResetMoveToTarget(); - updated = true; + if (m_moveToPositionInProgress) + { + ResetMoveToTarget(); + updated = true; + } + + return updated; } // m_log.DebugFormat( @@ -1576,8 +1581,7 @@ namespace OpenSim.Region.Framework.Scenes if (distanceToTarget <= 1) { // We are close enough to the target - MoveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; + ResetMoveToTarget(); updated = true; } else @@ -1660,6 +1664,10 @@ namespace OpenSim.Region.Framework.Scenes updated = true; } +// m_log.DebugFormat( +// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", +// LocalVectorToTarget3D, agent_control_v3, Name); + agent_control_v3 += LocalVectorToTarget3D; } catch (Exception e) @@ -1711,8 +1719,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void ResetMoveToTarget() { - MoveToPositionTarget = Vector3.Zero; +// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); + m_moveToPositionInProgress = false; + MoveToPositionTarget = Vector3.Zero; } private void CheckAtSitTarget() -- cgit v1.1 From 0299cb060eb55c6b7d068d74d2b9ccc0c607381e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 00:06:01 +0100 Subject: eliminate a reset position flag by using functionally equivalent DCFlagKeyPressed --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 71dd2eb..9f7bd9d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1417,7 +1417,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentID == 0) { bool bAllowUpdateMoveToPosition = false; - bool bResetMoveToPosition = false; Vector3[] dirVectors; @@ -1436,8 +1435,8 @@ namespace OpenSim.Region.Framework.Scenes { if (((uint)flags & (uint)DCF) != 0) { - bResetMoveToPosition = true; DCFlagKeyPressed = true; + try { agent_control_v3 += dirVectors[i]; @@ -1485,7 +1484,9 @@ namespace OpenSim.Region.Framework.Scenes i++; } - if (HandleMoveToPositionUpdate(ref agent_control_v3, bodyRotation, bResetMoveToPosition, bAllowUpdateMoveToPosition)) + // If the user has pressed a key then we want to cancel any move to target. + if (HandleMoveToPositionUpdate( + ref agent_control_v3, bodyRotation, DCFlagKeyPressed, bAllowUpdateMoveToPosition)) update_movementflag = true; } -- cgit v1.1 From a2f5b4ac9afeec2b8f44ba09d7236a134f187bfe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 00:10:53 +0100 Subject: Rename HandleMoveToPositionUpdate() to HandleMoveToTargetUpdate() for consistency. Improve method doc. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++++++------ OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9f7bd9d..4c83def 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1485,7 +1485,7 @@ namespace OpenSim.Region.Framework.Scenes } // If the user has pressed a key then we want to cancel any move to target. - if (HandleMoveToPositionUpdate( + if (HandleMoveToTargetUpdate( ref agent_control_v3, bodyRotation, DCFlagKeyPressed, bAllowUpdateMoveToPosition)) update_movementflag = true; } @@ -1539,20 +1539,20 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Process move to update for an avatar. + /// Calculate an update to move the presence to the set target. /// /// - /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3 + /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3. /// /// Cumulative agent movement that this method will update. /// New body rotation of the avatar. /// If true, clear the move to position /// If true, allow the update in principle. /// True if movement has been updated in some way. False otherwise. - public bool HandleMoveToPositionUpdate( + public bool HandleMoveToTargetUpdate( ref Vector3 agent_control_v3, Quaternion bodyRotation, bool reset, bool allowUpdate) { -// m_log.DebugFormat("[SCENE PRESENCE]: Called DoMoveToPositionUpdate() for {0}", Name); +// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); bool updated = false; @@ -1711,7 +1711,7 @@ namespace OpenSim.Region.Framework.Scenes MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); - HandleMoveToPositionUpdate(ref agent_control_v3, Rotation, false, true); + HandleMoveToTargetUpdate(ref agent_control_v3, Rotation, false, true); AddNewMovement(agent_control_v3, Rotation); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index f9c41d7..dd94240 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -86,7 +86,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC else { Vector3 agent_control_v3 = new Vector3(); - presence.HandleMoveToPositionUpdate(ref agent_control_v3, presence.Rotation, false, true); + presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation, false, true); presence.AddNewMovement(agent_control_v3, presence.Rotation); } // -- cgit v1.1 From 6f913e8caf8f913a3ad9456905a9a3ea0c48c97c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 00:13:27 +0100 Subject: eliminate pre-existing unused SP.StopMovement() --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4c83def..e90e7fd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1075,14 +1075,7 @@ namespace OpenSim.Region.Framework.Scenes SendTerseUpdateToAllClients(); } - - /// - /// - /// - public void StopMovement() - { - } - + public void StopFlying() { ControllingClient.StopFlying(this); -- cgit v1.1 From ba0c65e028ecd3c19a11e6e5557fb004f9dc6c01 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 00:25:51 +0100 Subject: extend npc move test to check a second movement --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 23 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e90e7fd..54ef039 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1075,7 +1075,7 @@ namespace OpenSim.Region.Framework.Scenes SendTerseUpdateToAllClients(); } - + public void StopFlying() { ControllingClient.StopFlying(this); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 57847f7..545819f 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -112,7 +112,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests scene.Update(); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); - Vector3 targetPos = new Vector3(128, 128, 40); + Vector3 targetPos = startPos + new Vector3(0, 0, 10); npcModule.MoveToTarget(npc.UUID, scene, targetPos); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); @@ -129,7 +129,26 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests scene.Update(); double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); - Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position"); + Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); + + // Try a second movement + startPos = npc.AbsolutePosition; + targetPos = startPos + new Vector3(10, 0, 0); + npcModule.MoveToTarget(npc.UUID, scene, targetPos); + + scene.Update(); + + // We should really check the exact figure. + Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); + Assert.That(npc.AbsolutePosition.X, Is.LessThan(targetPos.X)); + Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); + Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); + + for (int i = 0; i < 10; i++) + scene.Update(); + + distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); + Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); } } } \ No newline at end of file -- cgit v1.1 From 7f6f100c5a93791e8af29bafcfb93cfd289d5e8b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:00:33 +0100 Subject: When the NPC reaches within the SIGNIFICANT_CLIENT_MOVEMENT distance of the target, move it directly to the target. This makes the movement exact. Regression test changed to check avatar reaches exact target. Also has the nice side effect of making NPC animations continue to work after the first movement (which wasn't working). However, avatar still pauses in mid-stride --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 5 +++-- OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 54ef039..ba10423 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1575,6 +1575,7 @@ namespace OpenSim.Region.Framework.Scenes if (distanceToTarget <= 1) { // We are close enough to the target + AbsolutePosition = MoveToPositionTarget; ResetMoveToTarget(); updated = true; } @@ -1713,7 +1714,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void ResetMoveToTarget() { -// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); + m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); m_moveToPositionInProgress = false; MoveToPositionTarget = Vector3.Zero; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index dd94240..fdc3485 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -70,12 +70,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position - if (distanceToTarget <= 1) + if (distanceToTarget <= 2) { // m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0} {1}", presence.Name, presence.UUID); // We are close enough to the target for now - presence.ResetMoveToTarget(); presence.Velocity = Vector3.Zero; + presence.AbsolutePosition = presence.MoveToPositionTarget; + presence.ResetMoveToTarget(); // FIXME: This doesn't work if (presence.PhysicsActor.Flying) diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 545819f..c9dddba 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -130,6 +130,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); + Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos)); // Try a second movement startPos = npc.AbsolutePosition; @@ -149,6 +150,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); + Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos)); } } } \ No newline at end of file -- cgit v1.1 From fc64cc2439278f442839c69a7d98125f47019613 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:05:43 +0100 Subject: Make SIGNIFICANT_MOVEMENT SP constant a top-level property so that other classes can use it. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 +++++++----- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ba10423..b7fa3b6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -89,6 +89,13 @@ namespace OpenSim.Region.Framework.Scenes /// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); + /// + /// Movement updates for agents in neighboring regions are sent directly to clients. + /// This value only affects how often agent positions are sent to neighbor regions + /// for things such as distance-based update prioritization + /// + public static readonly float SIGNIFICANT_MOVEMENT = 2.0f; + public UUID currentParcelUUID = UUID.Zero; private ISceneViewer m_sceneViewer; @@ -2718,11 +2725,6 @@ namespace OpenSim.Region.Framework.Scenes /// protected void CheckForSignificantMovement() { - // Movement updates for agents in neighboring regions are sent directly to clients. - // This value only affects how often agent positions are sent to neighbor regions - // for things such as distance-based update prioritization - const float SIGNIFICANT_MOVEMENT = 2.0f; - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = AbsolutePosition; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index fdc3485..a0a24f2 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position - if (distanceToTarget <= 2) + if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) { // m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0} {1}", presence.Name, presence.UUID); // We are close enough to the target for now -- cgit v1.1 From 7b2b47530e48153b53c00cd33356abbbdb13d0b5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:16:24 +0100 Subject: move reset code out of HandleMoveToTargetUpdate() so that we only call it where needed instead of passing in a flag --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 28 ++++++++++------------ .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b7fa3b6..d471414 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1485,9 +1485,17 @@ namespace OpenSim.Region.Framework.Scenes } // If the user has pressed a key then we want to cancel any move to target. - if (HandleMoveToTargetUpdate( - ref agent_control_v3, bodyRotation, DCFlagKeyPressed, bAllowUpdateMoveToPosition)) + if (DCFlagKeyPressed && m_moveToPositionInProgress) + { + ResetMoveToTarget(); update_movementflag = true; + } + else + { + if (HandleMoveToTargetUpdate( + ref agent_control_v3, bodyRotation, bAllowUpdateMoveToPosition)) + update_movementflag = true; + } } // Cause the avatar to stop flying if it's colliding @@ -1546,27 +1554,15 @@ namespace OpenSim.Region.Framework.Scenes /// /// Cumulative agent movement that this method will update. /// New body rotation of the avatar. - /// If true, clear the move to position /// If true, allow the update in principle. /// True if movement has been updated in some way. False otherwise. public bool HandleMoveToTargetUpdate( - ref Vector3 agent_control_v3, Quaternion bodyRotation, bool reset, bool allowUpdate) + ref Vector3 agent_control_v3, Quaternion bodyRotation, bool allowUpdate) { // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); bool updated = false; - if (reset) - { - if (m_moveToPositionInProgress) - { - ResetMoveToTarget(); - updated = true; - } - - return updated; - } - // m_log.DebugFormat( // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); @@ -1712,7 +1708,7 @@ namespace OpenSim.Region.Framework.Scenes MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); - HandleMoveToTargetUpdate(ref agent_control_v3, Rotation, false, true); + HandleMoveToTargetUpdate(ref agent_control_v3, Rotation, true); AddNewMovement(agent_control_v3, Rotation); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index a0a24f2..fa60653 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -87,7 +87,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC else { Vector3 agent_control_v3 = new Vector3(); - presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation, false, true); + presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation, true); presence.AddNewMovement(agent_control_v3, presence.Rotation); } // -- cgit v1.1 From 831f933ce63eb8cf2bb24c1258ae5aeff394740f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:22:01 +0100 Subject: only call move target code in SP.HandleAgentUpdate() if we're actually in the process of moving to a position --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d471414..bb15a45 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1484,17 +1484,20 @@ namespace OpenSim.Region.Framework.Scenes i++; } - // If the user has pressed a key then we want to cancel any move to target. - if (DCFlagKeyPressed && m_moveToPositionInProgress) + if (m_moveToPositionInProgress) { - ResetMoveToTarget(); - update_movementflag = true; - } - else - { - if (HandleMoveToTargetUpdate( - ref agent_control_v3, bodyRotation, bAllowUpdateMoveToPosition)) + // If the user has pressed a key then we want to cancel any move to target. + if (DCFlagKeyPressed) + { + ResetMoveToTarget(); update_movementflag = true; + } + else + { + if (HandleMoveToTargetUpdate( + ref agent_control_v3, bodyRotation, bAllowUpdateMoveToPosition)) + update_movementflag = true; + } } } -- cgit v1.1 From 61a931490dae6a10adc915788bc661680be6778c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:30:37 +0100 Subject: move bAllowUpdateMoveToPosition switch outside of HandleMoveToTargetUpdate() --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 13 +++++-------- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bb15a45..620db94 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1492,10 +1492,9 @@ namespace OpenSim.Region.Framework.Scenes ResetMoveToTarget(); update_movementflag = true; } - else + else if (bAllowUpdateMoveToPosition) { - if (HandleMoveToTargetUpdate( - ref agent_control_v3, bodyRotation, bAllowUpdateMoveToPosition)) + if (HandleMoveToTargetUpdate(ref agent_control_v3, bodyRotation)) update_movementflag = true; } } @@ -1557,10 +1556,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// Cumulative agent movement that this method will update. /// New body rotation of the avatar. - /// If true, allow the update in principle. /// True if movement has been updated in some way. False otherwise. - public bool HandleMoveToTargetUpdate( - ref Vector3 agent_control_v3, Quaternion bodyRotation, bool allowUpdate) + public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3, Quaternion bodyRotation) { // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); @@ -1570,7 +1567,7 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); - if (allowUpdate && (m_moveToPositionInProgress && !m_autopilotMoving)) + if (!m_autopilotMoving) { double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); // m_log.DebugFormat( @@ -1711,7 +1708,7 @@ namespace OpenSim.Region.Framework.Scenes MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); - HandleMoveToTargetUpdate(ref agent_control_v3, Rotation, true); + HandleMoveToTargetUpdate(ref agent_control_v3, Rotation); AddNewMovement(agent_control_v3, Rotation); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index fa60653..2215495 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -87,7 +87,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC else { Vector3 agent_control_v3 = new Vector3(); - presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation, true); + presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation); presence.AddNewMovement(agent_control_v3, presence.Rotation); } // -- cgit v1.1 From c678b75d65f796f48ae0aacab7325c3aedb0d999 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:45:56 +0100 Subject: if a move to target is set underground, constrain it to the terrain height --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 620db94..98e90b9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1635,7 +1635,6 @@ namespace OpenSim.Region.Framework.Scenes if (LocalVectorToTarget3D.Y > 0) //MoveLeft { m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - //AgentControlFlags AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; updated = true; } @@ -1704,6 +1703,9 @@ namespace OpenSim.Region.Framework.Scenes // pos.Z = AbsolutePosition.Z; // } + float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; + pos.Z = Math.Max(terrainHeight, pos.Z); + m_moveToPositionInProgress = true; MoveToPositionTarget = pos; -- cgit v1.1 From f999acd095a71fb054e34a3987a13828bc2d3427 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 01:46:34 +0100 Subject: minor: remove some mono compiler warnings --- .../Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs | 4 ++-- OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs index 14160ae..66b865f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs @@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class BunchOfCapsModule : INonSharedRegionModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_Scene; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs index 29a9199..18c7eae 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs @@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class MeshUploadFlagModule : INonSharedRegionModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Is this module enabled? -- cgit v1.1 From 54ce0293423b4286fe62cbadc3b1441cae5f78eb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 02:31:40 +0100 Subject: if an NPC move to target is above the terrain then make it fly to destination --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 26 ++++++++++++++++------ .../Region/OptionalModules/World/NPC/NPCModule.cs | 10 ++++++--- 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 98e90b9..17b55bf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -217,8 +217,7 @@ namespace OpenSim.Region.Framework.Scenes private string m_nextSitAnimation = String.Empty; //PauPaw:Proper PID Controler for autopilot************ - private bool m_moveToPositionInProgress; - + public bool MovingToTarget { get; private set; } public Vector3 MoveToPositionTarget { get; private set; } private bool m_followCamAuto; @@ -1385,7 +1384,7 @@ namespace OpenSim.Region.Framework.Scenes if (agentData.UseClientAgentPosition) { - m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; + MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; MoveToPositionTarget = agentData.ClientAgentPosition; } @@ -1484,7 +1483,7 @@ namespace OpenSim.Region.Framework.Scenes i++; } - if (m_moveToPositionInProgress) + if (MovingToTarget) { // If the user has pressed a key then we want to cancel any move to target. if (DCFlagKeyPressed) @@ -1539,7 +1538,7 @@ namespace OpenSim.Region.Framework.Scenes && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround - && !m_moveToPositionInProgress) + && !MovingToTarget) Animator.UpdateMovementAnimations(); } @@ -1706,7 +1705,20 @@ namespace OpenSim.Region.Framework.Scenes float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; pos.Z = Math.Max(terrainHeight, pos.Z); - m_moveToPositionInProgress = true; + // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is + // always slightly higher than the actual terrain height. + // FIXME: This constrains NOC movements as well, so should be somewhere else. + if (pos.Z - terrainHeight < 0.2) + pos.Z = terrainHeight; + +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", +// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); + + if (pos.Z > terrainHeight) + PhysicsActor.Flying = true; + + MovingToTarget = true; MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); @@ -1721,7 +1733,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); - m_moveToPositionInProgress = false; + MovingToTarget = false; MoveToPositionTarget = Vector3.Zero; } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 2215495..30e81fc 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -62,7 +62,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { lock (m_avatars) { - if (m_avatars.ContainsKey(presence.UUID)) + if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget) { double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget); // m_log.DebugFormat( @@ -72,8 +72,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC // Check the error term of the current position in relation to the target position if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) { -// m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0} {1}", presence.Name, presence.UUID); - // We are close enough to the target for now + m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name); + // We are close enough to the target presence.Velocity = Vector3.Zero; presence.AbsolutePosition = presence.MoveToPositionTarget; presence.ResetMoveToTarget(); @@ -86,6 +86,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC } else { + m_log.DebugFormat( + "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}", + presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); + Vector3 agent_control_v3 = new Vector3(); presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation); presence.AddNewMovement(agent_control_v3, presence.Rotation); -- cgit v1.1 From 1918402cb181a39f8c085a409909dccb5c988aa1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Aug 2011 03:08:35 +0100 Subject: if an NPC target is set to a ground location, then automatically land them when they get there. This doesn't help where the target is a prim surface. In these situations, it might be better to provide manual overrides so the script can control whethre an avatar flys there/lands, etc. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++++----- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 13 ++++++++++++- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 17b55bf..d40132e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1537,8 +1537,7 @@ namespace OpenSim.Region.Framework.Scenes if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) - && !SitGround - && !MovingToTarget) + && !SitGround) Animator.UpdateMovementAnimations(); } @@ -1711,9 +1710,9 @@ namespace OpenSim.Region.Framework.Scenes if (pos.Z - terrainHeight < 0.2) pos.Z = terrainHeight; -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", -// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); + m_log.DebugFormat( + "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", + Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); if (pos.Z > terrainHeight) PhysicsActor.Flying = true; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 30e81fc..4f21d9d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -72,8 +72,19 @@ namespace OpenSim.Region.OptionalModules.World.NPC // Check the error term of the current position in relation to the target position if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) { - m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name); // We are close enough to the target + m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name); + + if (presence.PhysicsActor.Flying) + { + Vector3 targetPos = presence.MoveToPositionTarget; + float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; + if (targetPos.Z - terrainHeight < 0.2) + { + presence.PhysicsActor.Flying = false; + } + } + presence.Velocity = Vector3.Zero; presence.AbsolutePosition = presence.MoveToPositionTarget; presence.ResetMoveToTarget(); -- cgit v1.1 From 94d496cf2b7704adbef2cac5c8341a48b73f5fd5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 5 Aug 2011 00:57:43 +0100 Subject: remove the largely unused copy/pasted HandleAgentRequestSit() method --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 51 +++++------------------- 1 file changed, 11 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d40132e..d354c0a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1890,7 +1890,7 @@ namespace OpenSim.Region.Framework.Scenes bool forceMouselook = false; //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); if (part != null) { // TODO: determine position to sit at based on scene geometry; don't trust offset from client @@ -1966,14 +1966,23 @@ namespace OpenSim.Region.Framework.Scenes HandleAgentSit(remoteClient, UUID); } + // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) { if (m_parentID != 0) { StandUp(); } + +// if (!String.IsNullOrEmpty(sitAnimation)) +// { +// m_nextSitAnimation = sitAnimation; +// } +// else +// { m_nextSitAnimation = "SIT"; - +// } + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); @@ -1998,7 +2007,6 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); } @@ -2196,44 +2204,7 @@ namespace OpenSim.Region.Framework.Scenes SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); } */ - public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) - { - if (m_parentID != 0) - { - StandUp(); - } - if (!String.IsNullOrEmpty(sitAnimation)) - { - m_nextSitAnimation = sitAnimation; - } - else - { - m_nextSitAnimation = "SIT"; - } - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part != null) - { - m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; - m_requestedSitTargetUUID = targetID; - - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //SitRayCastAvatarPosition(part); - //return; - } - } - else - { - m_log.Warn("Sit requested on unknown object: " + targetID); - } - - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); - } public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) { -- cgit v1.1 From 7640b5abf651e51ae2efd5f79f440768a595dbc9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 5 Aug 2011 11:01:27 -0700 Subject: BulletSim: Parameters settable from ini file. Linksets. Physical property value tuning --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 11 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 267 ++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 207 +++++++++------- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 44 +++- 4 files changed, 316 insertions(+), 213 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 82361ad..9f9ebcc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -51,8 +51,6 @@ public class BSCharacter : PhysicsActor private Vector3 _position; private float _mass = 80f; public float _density = 60f; - public float CAPSULE_RADIUS = 0.37f; - public float CAPSULE_LENGTH = 2.140599f; private Vector3 _force; private Vector3 _velocity; private Vector3 _torque; @@ -96,7 +94,8 @@ public class BSCharacter : PhysicsActor _velocity = Vector3.Zero; _buoyancy = 0f; // characters return a buoyancy of zero _scale = new Vector3(1f, 1f, 1f); - float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH); + float AVvolume = (float) (Math.PI*Math.Pow(_scene.Params.avatarCapsuleRadius, 2)*_scene.Params.avatarCapsuleHeight); + _density = _scene.Params.avatarDensity; _mass = _density*AVvolume; ShapeData shapeData = new ShapeData(); @@ -109,6 +108,8 @@ public class BSCharacter : PhysicsActor shapeData.Mass = _mass; shapeData.Buoyancy = isFlying ? 1f : 0f; shapeData.Static = ShapeData.numericFalse; + shapeData.Friction = _scene.Params.avatarFriction; + shapeData.Restitution = _scene.Params.defaultRestitution; // do actual create at taint time _scene.TaintedObject(delegate() @@ -395,9 +396,9 @@ public class BSCharacter : PhysicsActor _acceleration = entprop.Acceleration; changed = true; } - if (_rotationalVelocity != entprop.AngularVelocity) + if (_rotationalVelocity != entprop.RotationalVelocity) { - _rotationalVelocity = entprop.AngularVelocity; + _rotationalVelocity = entprop.RotationalVelocity; changed = true; } if (changed) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f2ab2d9..04cb452 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -71,6 +71,7 @@ public sealed class BSPrim : PhysicsActor private bool _isPhysical; private bool _flying; private float _friction; + private float _restitution; private bool _setAlwaysRun; private bool _throttleUpdates; private bool _isColliding; @@ -101,7 +102,7 @@ public sealed class BSPrim : PhysicsActor private float _PIDHoverTao; public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, - OMV.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical) + OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) { // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _localID = localID; @@ -113,15 +114,16 @@ public sealed class BSPrim : PhysicsActor _orientation = rotation; _buoyancy = 1f; _velocity = OMV.Vector3.Zero; + _rotationalVelocity = OMV.Vector3.Zero; _angularVelocity = OMV.Vector3.Zero; - _mesh = mesh; _hullKey = 0; _pbs = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; _subscribedEventsMs = 0; - _friction = _scene.DefaultFriction; // TODO: compute based on object material - _density = _scene.DefaultDensity; // TODO: compute based on object material + _friction = _scene.Params.defaultFriction; // TODO: compute based on object material + _density = _scene.Params.defaultDensity; // TODO: compute based on object material + _restitution = _scene.Params.defaultRestitution; _parentPrim = null; // not a child or a parent _vehicle = new BSDynamics(this); // add vehicleness _childrenPrims = new List(); @@ -132,8 +134,7 @@ public sealed class BSPrim : PhysicsActor // do the actual object creation at taint time _scene.TaintedObject(delegate() { - CreateGeom(); - CreateObject(); + RecreateGeomAndObject(); }); } @@ -239,6 +240,7 @@ public sealed class BSPrim : PhysicsActor return; } + // I am the root of a linkset and a new child is being added public void AddChildToLinkset(BSPrim pchild) { BSPrim child = pchild; @@ -254,6 +256,8 @@ public sealed class BSPrim : PhysicsActor return; } + // I am the root of a linkset and one of my children is being removed. + // Safe to call even if the child is not really in my linkset. public void RemoveChildFromLinkset(BSPrim pchild) { BSPrim child = pchild; @@ -290,6 +294,17 @@ public sealed class BSPrim : PhysicsActor get { return (_parentPrim == null && _childrenPrims.Count != 0); } } + // Set motion values to zero. + // Do it to the properties so the values get set in the physics engine. + // Push the setting of the values to the viewer. + private void ZeroMotion() + { + Velocity = OMV.Vector3.Zero; + _acceleration = OMV.Vector3.Zero; + RotationalVelocity = OMV.Vector3.Zero; + base.RequestPhysicsterseUpdate(); + } + public override void LockAngularMotion(OMV.Vector3 axis) { return; } public override OMV.Vector3 Position { @@ -390,18 +405,6 @@ public sealed class BSPrim : PhysicsActor }); } } - public OMV.Vector3 AngularVelocity - { - get { return _angularVelocity; } - set - { - _angularVelocity = value; - _scene.TaintedObject(delegate() - { - BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _angularVelocity); - }); - } - } public override OMV.Vector3 Torque { get { return _torque; } set { _torque = value; @@ -419,11 +422,11 @@ public sealed class BSPrim : PhysicsActor get { return _orientation; } set { _orientation = value; + // m_log.DebugFormat("{0}: set orientation: id={1}, ori={2}", LogHeader, LocalID, _orientation); _scene.TaintedObject(delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); - // m_log.DebugFormat("{0}: set orientation: {1}", LogHeader, _orientation); }); } } @@ -505,8 +508,16 @@ public sealed class BSPrim : PhysicsActor get { return _rotationalVelocity; } set { _rotationalVelocity = value; // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); + _scene.TaintedObject(delegate() + { + BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); + }); } } + public OMV.Vector3 AngularVelocity { + get { return _angularVelocity; } + set { _angularVelocity = value; } + } public override bool Kinematic { get { return _kinematic; } set { _kinematic = value; @@ -866,9 +877,6 @@ public sealed class BSPrim : PhysicsActor returnMass = _density * volume; - if (returnMass <= 0) - returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. - if (IsRootOfLinkset) { foreach (BSPrim prim in _childrenPrims) @@ -877,8 +885,12 @@ public sealed class BSPrim : PhysicsActor } } - if (returnMass > _scene.maximumMassObject) - returnMass = _scene.maximumMassObject; + if (returnMass <= 0) + returnMass = 0.0001f; + + if (returnMass > _scene.MaximumObjectMass) + returnMass = _scene.MaximumObjectMass; + return returnMass; }// end CalculateMass #endregion Mass Calculation @@ -887,6 +899,15 @@ public sealed class BSPrim : PhysicsActor // No locking here because this is done when we know physics is not simulating private void CreateGeom() { + // Since we're recreating new, get rid of any previously generated shape + if (_hullKey != 0) + { + // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); + BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); + _hullKey = 0; + _hulls.Clear(); + } + if (_mesh == null) { // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. @@ -902,21 +923,13 @@ public sealed class BSPrim : PhysicsActor } else { - // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to box of size {1}", LogHeader, _size); + // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _scale = _size; } } else { - if (_hullKey != 0) - { - // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); - BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); - _hullKey = 0; - _hulls.Clear(); - } - int[] indices = _mesh.getIndexListAsInt(); List vertices = _mesh.getVertexList(); @@ -997,7 +1010,7 @@ public sealed class BSPrim : PhysicsActor // create the hull definition in Bullet _hullKey = (ulong)_pbs.GetHashCode(); - // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid= {1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); + // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; // meshes are already scaled by the meshmerizer @@ -1006,6 +1019,8 @@ public sealed class BSPrim : PhysicsActor return; } + // Callback from convex hull creater with a newly created hull. + // Just add it to the collection of hulls for this shape. private void HullReturn(ConvexResult result) { _hulls.Add(result); @@ -1019,13 +1034,12 @@ public sealed class BSPrim : PhysicsActor if (IsRootOfLinkset) { // Create a linkset around this object - CreateLinksetWithCompoundHull(); - // CreateLinksetWithConstraints(); + // CreateLinksetWithCompoundHull(); + CreateLinksetWithConstraints(); } else { // simple object - // m_log.DebugFormat("{0}: CreateObject. ID={1}", LogHeader, LocalID); ShapeData shape; FillShapeInfo(out shape); BulletSimAPI.CreateObject(_scene.WorldID, shape); @@ -1034,6 +1048,7 @@ public sealed class BSPrim : PhysicsActor // Create a linkset by creating a compound hull at the root prim that consists of all // the children. + // NOTE: This does not allow proper collisions with the children prims so it is not a workable solution void CreateLinksetWithCompoundHull() { // If I am the root prim of a linkset, replace my physical shape with all the @@ -1055,8 +1070,27 @@ public sealed class BSPrim : PhysicsActor BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes); } + // Copy prim's info into the BulletSim shape description structure + public void FillShapeInfo(out ShapeData shape) + { + shape.ID = _localID; + shape.Type = _shapeType; + shape.Position = _position; + shape.Rotation = _orientation; + shape.Velocity = _velocity; + shape.Scale = _scale; + shape.Mass = _isPhysical ? _mass : 0f; + shape.Buoyancy = _buoyancy; + shape.MeshKey = _hullKey; + shape.Friction = _friction; + shape.Restitution = _restitution; + shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; + shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; + } + // Create the linkset by putting constraints between the objects of the set so they cannot move // relative to each other. + // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added void CreateLinksetWithConstraints() { // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); @@ -1070,76 +1104,48 @@ public sealed class BSPrim : PhysicsActor // create constraints between the root prim and each of the children foreach (BSPrim prim in _childrenPrims) { - // this is a constraint that allows no freedom of movement between the two objects - // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // m_log.DebugFormat("{0}: CreateObject: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); + // Zero motion for children so they don't interpolate + prim.ZeroMotion(); + // relative position normalized to the root prim OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation); - // OMV.Quaternion relativeRotation = OMV.Quaternion.Identity; - // rotation is pointing up the vector between the object centers - OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromAxisAngle(childRelativePosition, 0f); - - /* // the logic for relative rotation from http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6391 - OMV.Vector3 rrn = childRelativePosition; - rrn.Normalize(); - rrn /= rrn.X; - OMV.Matrix4 rotmat = new OMV.Matrix4(rrn.X, rrn.Y, rrn.Z, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromRotationMatrix(rotmat); - */ + // relative rotation of the child to the parent + OMV.Quaternion relativeRotation = OMV.Quaternion.Inverse(prim._orientation) * this._orientation; + // this is a constraint that allows no freedom of movement between the two objects + // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, - childRelativePosition / 2, - relativeRotation, - -childRelativePosition / 2, + childRelativePosition, relativeRotation, + OMV.Vector3.Zero, + OMV.Quaternion.Identity, OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero); } } - // Copy prim's info into the BulletSim shape description structure - public void FillShapeInfo(out ShapeData shape) - { - shape.ID = _localID; - shape.Type = _shapeType; - shape.Position = _position; - shape.Rotation = _orientation; - shape.Velocity = _velocity; - shape.Scale = _scale; - shape.Mass = _isPhysical ? _mass : 0f; - shape.Buoyancy = _buoyancy; - shape.MeshKey = _hullKey; - shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; - shape.Friction = _friction; - shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; - } - // Rebuild the geometry and object. // This is called when the shape changes so we need to recreate the mesh/hull. // No locking here because this is done when the physics engine is not simulating private void RecreateGeomAndObject() { - if (_hullKey != 0) - { - // if a hull already exists, delete the old one - BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); - _hullKey = 0; - } // If this object is complex or we are the root of a linkset, build a mesh. // The root of a linkset must be a mesh so we can create the linked compound object. - if (_scene.NeedsMeshing(_pbs) || IsRootOfLinkset ) + // if (_scene.NeedsMeshing(_pbs) || IsRootOfLinkset ) + if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh { // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); - _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.meshLOD, _isPhysical); + _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.MeshLOD, _isPhysical); } else { - // it's a BulletSim native shape. + // implement the shape with a Bullet native shape. _mesh = null; } - CreateGeom(); // create the geometry for this prim + CreateGeom(); CreateObject(); return; } @@ -1152,48 +1158,82 @@ public sealed class BSPrim : PhysicsActor Rotation = 1 << 1, Velocity = 1 << 2, Acceleration = 1 << 3, - AngularVel = 1 << 4 + RotationalVel = 1 << 4 } + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; + const float ACCELERATION_TOLERANCE = 0.01f; + const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; + const bool SHOULD_DAMP_UPDATES = false; + public void UpdateProperties(EntityProperties entprop) { UpdatedProperties changed = 0; - // assign to the local variables so the normal set action does not happen - if (_position != entprop.Position) - { - _position = entprop.Position; - // m_log.DebugFormat("{0}: UpdateProperties: position = {1}", LogHeader, _position); - changed |= UpdatedProperties.Position; - } - if (_orientation != entprop.Rotation) - { - _orientation = entprop.Rotation; - // m_log.DebugFormat("{0}: UpdateProperties: rotation = {1}", LogHeader, _orientation); - changed |= UpdatedProperties.Rotation; - } - if (_velocity != entprop.Velocity) - { - _velocity = entprop.Velocity; - // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity); - changed |= UpdatedProperties.Velocity; - } - if (_acceleration != entprop.Acceleration) - { - _acceleration = entprop.Acceleration; - // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration); - changed |= UpdatedProperties.Acceleration; - } - if (_rotationalVelocity != entprop.AngularVelocity) + if (SHOULD_DAMP_UPDATES) { - _rotationalVelocity = entprop.AngularVelocity; - // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); - changed |= UpdatedProperties.AngularVel; + // assign to the local variables so the normal set action does not happen + // if (_position != entprop.Position) + if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE)) + { + _position = entprop.Position; + // m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position); + changed |= UpdatedProperties.Position; + } + // if (_orientation != entprop.Rotation) + if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE)) + { + _orientation = entprop.Rotation; + // m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation); + changed |= UpdatedProperties.Rotation; + } + // if (_velocity != entprop.Velocity) + if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE)) + { + _velocity = entprop.Velocity; + // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity); + changed |= UpdatedProperties.Velocity; + } + // if (_acceleration != entprop.Acceleration) + if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE)) + { + _acceleration = entprop.Acceleration; + // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration); + changed |= UpdatedProperties.Acceleration; + } + // if (_rotationalVelocity != entprop.RotationalVelocity) + if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE)) + { + _rotationalVelocity = entprop.RotationalVelocity; + // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); + changed |= UpdatedProperties.RotationalVel; + } + if (changed != 0) + { + // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); + // Only update the position of single objects and linkset roots + if (this._parentPrim == null) + { + // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); + base.RequestPhysicsterseUpdate(); + } + } } - if (changed != 0) + else { - // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); + // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. if (this._parentPrim == null) + { + // Assign to the local variables so the normal set action does not happen + _position = entprop.Position; + _orientation = entprop.Rotation; + _velocity = entprop.Velocity; + _acceleration = entprop.Acceleration; + _rotationalVelocity = entprop.RotationalVelocity; + // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); base.RequestPhysicsterseUpdate(); + } } } @@ -1201,7 +1241,8 @@ public sealed class BSPrim : PhysicsActor public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); - // The following makes IsColliding() and IsCollidingGround() work + + // The following lines make IsColliding() and IsCollidingGround() work _collidingStep = _scene.SimulationStep; if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7c11f2b..de86d59 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -71,11 +71,17 @@ public class BSScene : PhysicsScene private uint m_worldID; public uint WorldID { get { return m_worldID; } } + private bool m_initialized = false; + public IMesher mesher; - public int meshLOD = 32; + private int m_meshLOD; + public int MeshLOD + { + get { return m_meshLOD; } + } - private int m_maxSubSteps = 10; - private float m_fixedTimeStep = 1f / 60f; + private int m_maxSubSteps; + private float m_fixedTimeStep; private long m_simulationStep = 0; public long SimulationStep { get { return m_simulationStep; } } @@ -84,68 +90,65 @@ public class BSScene : PhysicsScene private int m_simulationNowTime; public int SimulationNowTime { get { return m_simulationNowTime; } } - private int m_maxCollisionsPerFrame = 2048; + private int m_maxCollisionsPerFrame; private CollisionDesc[] m_collisionArray; private GCHandle m_collisionArrayPinnedHandle; - private int m_maxUpdatesPerFrame = 2048; + private int m_maxUpdatesPerFrame; private EntityProperties[] m_updateArray; private GCHandle m_updateArrayPinnedHandle; private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes - public float maximumMassObject = 10000.01f; - public const uint TERRAIN_ID = 0; + public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero public const uint GROUNDPLANE_ID = 1; - public float DefaultFriction = 0.70f; - public float DefaultDensity = 10.000006836f; // Aluminum g/cm3; TODO: compute based on object material - public Vector3 DefaultGravity = new Vector3(0, 0, -9.80665f); + public ConfigurationParameters Params + { + get { return m_params[0]; } + } + public Vector3 DefaultGravity + { + get { return new Vector3(0f, 0f, Params.gravity); } + } + + private float m_maximumObjectMass; + public float MaximumObjectMass + { + get { return m_maximumObjectMass; } + } public delegate void TaintCallback(); private List _taintedObjects; private Object _taintLock = new Object(); // A pointer to an instance if this structure is passed to the C++ code - // Format of this structure must match the definition in the C++ code - private struct ConfigurationParameters - { - public float defaultFriction; - public float defaultDensity; - public float collisionMargin; - public float gravity; - - public float linearDamping; - public float angularDamping; - public float deactivationTime; - public float linearSleepingThreshold; - public float angularSleepingThreshold; - - public float terrainFriction; - public float terrainHitFriction; - public float terrainRestitution; - public float avatarFriction; - public float avatarCapsuleRadius; - public float avatarCapsuleHeight; - } - ConfigurationParameters m_params; + ConfigurationParameters[] m_params; GCHandle m_paramsHandle; private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; public BSScene(string identifier) { + m_initialized = false; } public override void Initialise(IMesher meshmerizer, IConfigSource config) { - m_params = new ConfigurationParameters(); + // Allocate pinned memory to pass parameters. + m_params = new ConfigurationParameters[1]; m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned); // Set default values for physics parameters plus any overrides from the ini file GetInitialParameterValues(config); + // allocate more pinned memory close to the above in an attempt to get the memory all together + m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; + m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); + m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; + m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + // if Debug, enable logging from the unmanaged code if (m_log.IsDebugEnabled) { @@ -160,68 +163,95 @@ public class BSScene : PhysicsScene // The bounding box for the simulated world Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f); - // Allocate pinned memory to pass back object property updates and collisions from simulation step - m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; - m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); - m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; - m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); - // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - m_worldID = BulletSimAPI.Initialize(worldExtent, + m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); + + m_initialized = true; } + // All default parameter values are set here. There should be no values set in the + // variable definitions. private void GetInitialParameterValues(IConfigSource config) { + ConfigurationParameters parms = new ConfigurationParameters(); + _meshSculptedPrim = true; // mesh sculpted prims _forceSimplePrimMeshing = false; // use complex meshing if called for - // Set the default values for the physics parameters - m_params.defaultFriction = 0.70f; - m_params.defaultDensity = 10.000006836f; // Aluminum g/cm3 - m_params.collisionMargin = 0.0f; - m_params.gravity = -9.80665f; - - m_params.linearDamping = 0.1f; - m_params.angularDamping = 0.85f; - m_params.deactivationTime = 0.2f; - m_params.linearSleepingThreshold = 0.8f; - m_params.angularSleepingThreshold = 1.0f; - - m_params.terrainFriction = 0.85f; - m_params.terrainHitFriction = 0.8f; - m_params.terrainRestitution = 0.2f; - m_params.avatarFriction = 0.85f; - m_params.avatarCapsuleRadius = 0.37f; - m_params.avatarCapsuleHeight = 1.5f; // 2.140599f + m_meshLOD = 32; + + m_maxSubSteps = 10; + m_fixedTimeStep = 1f / 60f; + m_maxCollisionsPerFrame = 2048; + m_maxUpdatesPerFrame = 2048; + m_maximumObjectMass = 10000.01f; + + parms.defaultFriction = 0.70f; + parms.defaultDensity = 10.000006836f; // Aluminum g/cm3 + parms.defaultRestitution = 0f; + parms.collisionMargin = 0.0f; + parms.gravity = -9.80665f; + + parms.linearDamping = 0.0f; + parms.angularDamping = 0.0f; + parms.deactivationTime = 0.2f; + parms.linearSleepingThreshold = 0.8f; + parms.angularSleepingThreshold = 1.0f; + parms.ccdMotionThreshold = 0.5f; // set to zero to disable + parms.ccdSweptSphereRadius = 0.2f; + + parms.terrainFriction = 0.85f; + parms.terrainHitFriction = 0.8f; + parms.terrainRestitution = 0.2f; + parms.avatarFriction = 0.85f; + parms.avatarDensity = 60f; + parms.avatarCapsuleRadius = 0.37f; + parms.avatarCapsuleHeight = 1.5f; // 2.140599f if (config != null) { // If there are specifications in the ini file, use those values + // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO ALSO UPDATE OpenSimDefaults.ini IConfig pConfig = config.Configs["BulletSim"]; if (pConfig != null) { - _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", true); - _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", false); - - m_params.defaultFriction = pConfig.GetFloat("DefaultFriction", m_params.defaultFriction); - m_params.defaultDensity = pConfig.GetFloat("DefaultDensity", m_params.defaultDensity); - m_params.collisionMargin = pConfig.GetFloat("CollisionMargin", m_params.collisionMargin); - m_params.gravity = pConfig.GetFloat("Gravity", m_params.gravity); - m_params.linearDamping = pConfig.GetFloat("LinearDamping", m_params.linearDamping); - m_params.angularDamping = pConfig.GetFloat("AngularDamping", m_params.angularDamping); - m_params.deactivationTime = pConfig.GetFloat("DeactivationTime", m_params.deactivationTime); - m_params.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", m_params.linearSleepingThreshold); - m_params.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", m_params.angularSleepingThreshold); - m_params.terrainFriction = pConfig.GetFloat("TerrainFriction", m_params.terrainFriction); - m_params.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", m_params.terrainHitFriction); - m_params.terrainRestitution = pConfig.GetFloat("TerrainRestitution", m_params.terrainRestitution); - m_params.avatarFriction = pConfig.GetFloat("AvatarFriction", m_params.avatarFriction); - m_params.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", m_params.avatarCapsuleRadius); - m_params.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", m_params.avatarCapsuleHeight); + _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); + _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); + + m_meshLOD = pConfig.GetInt("MeshLevelOfDetail", m_meshLOD); + + m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps); + m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep); + m_maxCollisionsPerFrame = pConfig.GetInt("MaxCollisionsPerFrame", m_maxCollisionsPerFrame); + m_maxUpdatesPerFrame = pConfig.GetInt("MaxUpdatesPerFrame", m_maxUpdatesPerFrame); + m_maximumObjectMass = pConfig.GetFloat("MaxObjectMass", m_maximumObjectMass); + + parms.defaultFriction = pConfig.GetFloat("DefaultFriction", parms.defaultFriction); + parms.defaultDensity = pConfig.GetFloat("DefaultDensity", parms.defaultDensity); + parms.defaultRestitution = pConfig.GetFloat("DefaultRestitution", parms.defaultRestitution); + parms.collisionMargin = pConfig.GetFloat("CollisionMargin", parms.collisionMargin); + parms.gravity = pConfig.GetFloat("Gravity", parms.gravity); + + parms.linearDamping = pConfig.GetFloat("LinearDamping", parms.linearDamping); + parms.angularDamping = pConfig.GetFloat("AngularDamping", parms.angularDamping); + parms.deactivationTime = pConfig.GetFloat("DeactivationTime", parms.deactivationTime); + parms.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", parms.linearSleepingThreshold); + parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold); + parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold); + parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); + + parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); + parms.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", parms.terrainHitFriction); + parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); + parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); + parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); + parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius); + parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight); } } + m_params[0] = parms; } // Called directly from unmanaged code so don't do much @@ -282,20 +312,13 @@ public class BSScene : PhysicsScene Vector3 size, Quaternion rotation, bool isPhysical, uint localID) { // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); - IMesh mesh = null; - if (NeedsMeshing(pbs)) - { - // if the prim is complex, create the mesh for it. - // If simple (box or sphere) leave 'mesh' null and physics will do a native shape. - mesh = mesher.CreateMesh(primName, pbs, size, this.meshLOD, isPhysical); - } - BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, mesh, pbs, isPhysical); + BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); lock (m_prims) m_prims.Add(localID, prim); return prim; } // This is a call from the simulator saying that some physical property has been updated. - // The BulletS driver senses the changing of relevant properties so this taint + // The BulletSim driver senses the changing of relevant properties so this taint // information call is not needed. public override void AddPhysicsActorTaint(PhysicsActor prim) { } @@ -307,6 +330,9 @@ public class BSScene : PhysicsScene int collidersCount; IntPtr collidersPtr; + // prevent simulation until we've been initialized + if (!m_initialized) return 10.0f; + // update the prim states while we know the physics engine is not busy ProcessTaints(); @@ -360,7 +386,7 @@ public class BSScene : PhysicsScene } } - // fps calculation wrong. This calculation always returns about 1 in normal operation. + // FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; } @@ -369,8 +395,7 @@ public class BSScene : PhysicsScene { if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) { - // we never send collisions to the terrain - return; + return; // don't send collisions to the terrain } ActorTypes type = ActorTypes.Prim; @@ -381,12 +406,12 @@ public class BSScene : PhysicsScene BSPrim prim; if (m_prims.TryGetValue(localID, out prim)) { - prim.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f); + prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); return; } BSCharacter actor; if (m_avatars.TryGetValue(localID, out actor)) { - actor.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f); + actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration); return; } return; @@ -448,7 +473,7 @@ public class BSScene : PhysicsScene if (pbs.SculptEntry && !_meshSculptedPrim) { - // m_log.DebugFormat("{0}: NeedsMeshing: scultpy mesh", LogHeader); + // Render sculpties as boxes return false; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index ace8158..819fce1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -32,12 +32,14 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { +[StructLayout(LayoutKind.Sequential)] public struct ConvexHull { Vector3 Offset; int VertexCount; Vector3[] Vertices; } +[StructLayout(LayoutKind.Sequential)] public struct ShapeData { public enum PhysicsShapeType @@ -49,6 +51,7 @@ public struct ShapeData SHAPE_SPHERE = 4, SHAPE_HULL = 5 }; + // note that bools are passed as ints since bool size changes by language public const int numericTrue = 1; public const int numericFalse = 0; public uint ID; @@ -60,11 +63,12 @@ public struct ShapeData public float Mass; public float Buoyancy; public System.UInt64 MeshKey; - public int Collidable; public float Friction; + public float Restitution; + public int Collidable; public int Static; // true if a static object. Otherwise gravity, etc. - // note that bools are passed as ints since bool size changes by language } +[StructLayout(LayoutKind.Sequential)] public struct SweepHit { public uint ID; @@ -72,12 +76,14 @@ public struct SweepHit public Vector3 Normal; public Vector3 Point; } +[StructLayout(LayoutKind.Sequential)] public struct RaycastHit { public uint ID; public float Fraction; public Vector3 Normal; } +[StructLayout(LayoutKind.Sequential)] public struct CollisionDesc { public uint aID; @@ -85,6 +91,7 @@ public struct CollisionDesc public Vector3 point; public Vector3 normal; } +[StructLayout(LayoutKind.Sequential)] public struct EntityProperties { public uint ID; @@ -92,13 +99,42 @@ public struct EntityProperties public Quaternion Rotation; public Vector3 Velocity; public Vector3 Acceleration; - public Vector3 AngularVelocity; + public Vector3 RotationalVelocity; +} + +// Format of this structure must match the definition in the C++ code +[StructLayout(LayoutKind.Sequential)] +public struct ConfigurationParameters +{ + public float defaultFriction; + public float defaultDensity; + public float defaultRestitution; + public float collisionMargin; + public float gravity; + + public float linearDamping; + public float angularDamping; + public float deactivationTime; + public float linearSleepingThreshold; + public float angularSleepingThreshold; + public float ccdMotionThreshold; + public float ccdSweptSphereRadius; + + public float terrainFriction; + public float terrainHitFriction; + public float terrainRestitution; + public float avatarFriction; + public float avatarDensity; + public float avatarRestitution; + public float avatarCapsuleRadius; + public float avatarCapsuleHeight; } static class BulletSimAPI { [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern uint Initialize(Vector3 maxPosition, int maxCollisions, IntPtr collisionArray, +public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, int maxUpdates, IntPtr updateArray); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -- cgit v1.1 From 1a2518d19bb447f4d3821cb71e32e712cc99d9c0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 5 Aug 2011 19:57:47 +0100 Subject: Instead of moving the file to its final place when FlotsamCache writes to disk, copy it instead. This is to eliminate IOException where two threads compete to cache the same file. --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index da39202..0c700e3 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -600,7 +600,13 @@ namespace Flotsam.RegionModules.AssetCache stream.Close(); // Now that it's written, rename it so that it can be found. - File.Move(tempname, filename); + // We're doing this as a file copy operation so that if two threads are competing to cache this asset, + // then both suceed instead of one failing when it tries to move the file to a final filename that + // already exists. + // This assumes that the file copy operation is atomic. Assuming this holds, then copying also works + // if another simulator is using the same cache directory. + File.Copy(tempname, filename, true); + File.Delete(tempname); if (m_LogLevel >= 2) m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); @@ -635,7 +641,6 @@ namespace Flotsam.RegionModules.AssetCache } #endif } - } } -- cgit v1.1 From 7d35bf819374a323fa737f8342a4239e0759ce8f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 5 Aug 2011 22:45:42 +0100 Subject: refactor: remove a sliver of unnecessary code --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 0c700e3..7ef759c 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -635,10 +635,7 @@ namespace Flotsam.RegionModules.AssetCache waitEvent.Set(); } #else - if (m_CurrentlyWriting.Contains(filename)) - { - m_CurrentlyWriting.Remove(filename); - } + m_CurrentlyWriting.Remove(filename); #endif } } -- cgit v1.1 From 82f41fdcb54d61e78f6ab8efdbbb521dfc5b9217 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 5 Aug 2011 14:53:39 -0700 Subject: BulletSim: fix problem with not convex hulling large objects by creating unit meshes and always scaling in Bullet --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 04cb452..c4999f6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1013,8 +1013,8 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; - // meshes are already scaled by the meshmerizer - _scale = new OMV.Vector3(1f, 1f, 1f); + // Let the object be scaled by Bullet (the mesh was created as a unit mesh) + _scale = _size; } return; } @@ -1138,7 +1138,9 @@ public sealed class BSPrim : PhysicsActor if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh { // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); - _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.MeshLOD, _isPhysical); + // Make the mesh scaled to 1 and use Bullet's scaling feature to scale it in world + OMV.Vector3 scaleFactor = new OMV.Vector3(1.0f, 1.0f, 1.0f); + _mesh = _scene.mesher.CreateMesh(_avName, _pbs, scaleFactor, _scene.MeshLOD, _isPhysical); } else { -- cgit v1.1 From ba89fc3aa1833c0fd6b5518d85ca966768597c6c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 5 Aug 2011 23:42:05 +0100 Subject: Add regression test for setting phantom status on a scene object. This is not yet complete. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 22 ++++---- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++- .../Scenes/Tests/SceneObjectStatusTests.cs | 62 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 57baa99..3b6a458 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2253,7 +2253,7 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void DetachFromBackup() { - if (m_isBackedUp) + if (m_isBackedUp && Scene != null) m_scene.EventManager.OnBackup -= ProcessBackup; m_isBackedUp = false; @@ -2520,7 +2520,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart selectionPart = GetChildPart(localID); - if (SetTemporary) + if (SetTemporary && Scene != null) { DetachFromBackup(); // Remove from database and parcel prim count @@ -2532,15 +2532,19 @@ namespace OpenSim.Region.Framework.Scenes if (selectionPart != null) { SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) + + if (Scene != null) { - SceneObjectPart part = parts[i]; - if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || - part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || - part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) + for (int i = 0; i < parts.Length; i++) { - UsePhysics = false; // Reset physics - break; + SceneObjectPart part = parts[i]; + if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || + part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || + part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) + { + UsePhysics = false; // Reset physics + break; + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 90ad34e..e8a1070 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -261,12 +261,9 @@ namespace OpenSim.Region.Framework.Scenes } protected SceneObjectPartInventory m_inventory; - public bool Undoing; - public bool IgnoreUndoUpdate = false; - private PrimFlags LocalFlags; @@ -4645,6 +4642,8 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); + +// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); } public void UpdateRotation(Quaternion rot) @@ -4864,7 +4863,7 @@ namespace OpenSim.Region.Framework.Scenes // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; //} - LocalFlags=(PrimFlags)objectflagupdate; + LocalFlags = (PrimFlags)objectflagupdate; if (m_parentGroup != null && m_parentGroup.RootPart == this) { diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs new file mode 100644 index 0000000..a26fe33 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -0,0 +1,62 @@ +/* + * 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.Reflection; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + /// + /// Basic scene object status tests + /// + [TestFixture] + public class SceneObjectStatusTests + { + [Test] + public void TestSetPhantom() + { + TestHelper.InMethod(); + +// Scene scene = SceneSetupHelpers.SetupScene(); + SceneObjectGroup so = SceneSetupHelpers.CreateSceneObject(1, UUID.Zero); + SceneObjectPart rootPart = so.RootPart; + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + + so.RootPart.ScriptSetPhantomStatus(true); + + Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); + } + } +} \ No newline at end of file -- cgit v1.1 From c6c91e6599de6d4402ec0258da03cc975147da90 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 00:13:08 +0100 Subject: refactor: Fold most SOP.ScriptSet* methods back into script code. Simplify. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 25 -------------------- .../Scenes/Tests/SceneObjectStatusTests.cs | 4 ++-- .../Shared/Api/Implementation/LSL_Api.cs | 27 ++++++---------------- 3 files changed, 9 insertions(+), 47 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e8a1070..afc386e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2967,22 +2967,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void ScriptSetPhantomStatus(bool Phantom) - { - if (m_parentGroup != null) - { - m_parentGroup.ScriptSetPhantomStatus(Phantom); - } - } - - public void ScriptSetTemporaryStatus(bool Temporary) - { - if (m_parentGroup != null) - { - m_parentGroup.ScriptSetTemporaryStatus(Temporary); - } - } - public void ScriptSetPhysicsStatus(bool UsePhysics) { if (m_parentGroup == null) @@ -2991,15 +2975,6 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.ScriptSetPhysicsStatus(UsePhysics); } - public void ScriptSetVolumeDetect(bool SetVD) - { - - if (m_parentGroup != null) - { - m_parentGroup.ScriptSetVolumeDetect(SetVD); - } - } - /// /// Set sculpt and mesh data, and tell the physics engine to process the change. /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index a26fe33..641c34e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -53,9 +53,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectPart rootPart = so.RootPart; Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); - so.RootPart.ScriptSetPhantomStatus(true); + so.ScriptSetPhantomStatus(true); - Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); +// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 26969a5..7c21ba9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1204,10 +1204,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM) { - if (value != 0) - m_host.ScriptSetPhantomStatus(true); - else - m_host.ScriptSetPhantomStatus(false); + if (m_host.ParentGroup != null) + m_host.ParentGroup.ScriptSetPhantomStatus(value != 0); } if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS) @@ -6446,9 +6444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.ParentGroup != null) { if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.ScriptSetVolumeDetect(detect!=0); - } + m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); } } @@ -6456,7 +6452,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// This is a depecated function so this just replicates the result of /// invoking it in SL /// - public void llRemoteLoadScript(string target, string name, int running, int start_param) { m_host.AddScriptLPS(1); @@ -7254,14 +7249,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; string ph = rules.Data[idx++].ToString(); - bool phantom; - if (ph.Equals("1")) - phantom = true; - else - phantom = false; + if (m_host.ParentGroup != null) + m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); - part.ScriptSetPhantomStatus(phantom); break; case (int)ScriptBaseClass.PRIM_PHYSICS: @@ -7282,14 +7273,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (remain < 1) return; string temp = rules.Data[idx++].ToString(); - bool tempOnRez; - if (temp.Equals("1")) - tempOnRez = true; - else - tempOnRez = false; + if (m_host.ParentGroup != null) + m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); - part.ScriptSetTemporaryStatus(tempOnRez); break; case (int)ScriptBaseClass.PRIM_TEXGEN: -- cgit v1.1 From cba40de109a0ab54a58324f105cbba799da70e39 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 00:22:14 +0100 Subject: extend phantom flag regression test to toggle back off --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +++ OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index afc386e..7778ebc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4514,6 +4514,9 @@ namespace OpenSim.Region.Framework.Scenes { RemFlag(PrimFlags.Phantom); + if (ParentGroup.Scene == null) + return; + PhysicsActor pa = PhysActor; if (pa == null) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 641c34e..c0fca5d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -57,6 +57,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); + + so.ScriptSetPhantomStatus(false); + + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); } } } \ No newline at end of file -- cgit v1.1 From bda1a4be4567181df6c18ce6e059ca8982bc5fa1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 00:26:37 +0100 Subject: rename test SceneSetupHelpers -> SceneHelpers for consistency --- .../Asset/Tests/FlotsamAssetCacheTests.cs | 4 +-- .../Tests/AvatarFactoryModuleTests.cs | 6 ++-- .../Archiver/Tests/InventoryArchiveTestCase.cs | 10 +++---- .../Archiver/Tests/InventoryArchiverTests.cs | 8 +++--- .../Avatar/Inventory/Archiver/Tests/PathTests.cs | 22 +++++++-------- .../Tests/InventoryAccessModuleTests.cs | 10 +++---- .../World/Archiver/Tests/ArchiverTests.cs | 8 +++--- .../World/Land/Tests/PrimCountModuleTests.cs | 32 +++++++++++----------- .../World/Media/Moap/Tests/MoapTests.cs | 8 +++--- .../World/Serialiser/Tests/SerialiserTests.cs | 4 +-- .../Framework/Scenes/Tests/AttachmentTests.cs | 14 +++++----- .../Framework/Scenes/Tests/EntityManagerTests.cs | 2 +- .../Framework/Scenes/Tests/SceneGraphTests.cs | 2 +- .../Scenes/Tests/SceneObjectBasicTests.cs | 14 +++++----- .../Scenes/Tests/SceneObjectDeRezTests.cs | 12 ++++---- .../Scenes/Tests/SceneObjectLinkingTests.cs | 20 +++++++------- .../Scenes/Tests/SceneObjectResizeTests.cs | 8 +++--- .../Scenes/Tests/SceneObjectStatusTests.cs | 2 +- .../Scenes/Tests/SceneObjectUserGroupTests.cs | 6 ++-- .../Framework/Scenes/Tests/ScenePresenceTests.cs | 20 +++++++------- .../Region/Framework/Scenes/Tests/SceneTests.cs | 2 +- .../Scenes/Tests/StandaloneTeleportTests.cs | 10 +++---- .../Framework/Scenes/Tests/TaskInventoryTests.cs | 12 ++++---- .../Framework/Scenes/Tests/UserInventoryTests.cs | 4 +-- .../Framework/Scenes/Tests/UuidGathererTests.cs | 2 +- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 4 +-- .../World/NPC/Tests/NPCModuleTests.cs | 12 ++++---- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 4 +-- 28 files changed, 131 insertions(+), 131 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 63b0c31..1662f19 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs @@ -65,8 +65,8 @@ namespace OpenSim.Region.CoreModules.Asset.Tests config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); m_cache = new FlotsamAssetCache(); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, config, m_cache); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, config, m_cache); } [Test] diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 07de908..c05f5ab 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -50,9 +50,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory UUID userId = TestHelper.ParseTail(0x1); AvatarFactoryModule afm = new AvatarFactoryModule(); - TestScene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, afm); - TestClient tc = SceneSetupHelpers.AddClient(scene, userId); + TestScene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, afm); + TestClient tc = SceneHelpers.AddClient(scene, userId); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index aadeedb..19ef571 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs @@ -100,8 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // log4net.Config.XmlConfigurator.Configure(); InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, archiverModule); + Scene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, archiverModule); UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // Create scene object asset UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50); UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); @@ -127,10 +127,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests scene.AddInventoryItem(item1); // Create coalesced objects asset - SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120); + SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120); cobj1.AbsolutePosition = new Vector3(15, 30, 45); - SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140); + SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140); cobj2.AbsolutePosition = new Vector3(25, 50, 75); CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index ae3ab21..3616ae2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -61,8 +61,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); m_archiverModule = new InventoryArchiverModule(); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); } [Test] @@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // Create asset UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); @@ -236,7 +236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // Create asset UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 127d5f8..1d3e5d0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs @@ -62,8 +62,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, archiverModule); + Scene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, archiverModule); // Create user string userFirstName = "Jock"; @@ -179,9 +179,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryArchiverModule archiverModule = new InventoryArchiverModule(); // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); + SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); @@ -222,8 +222,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); + Scene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); @@ -247,8 +247,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, archiverModule); + Scene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, archiverModule); // Create user string userFirstName = "Jock"; @@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); Dictionary foldersCreated = new Dictionary(); @@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); string folder1ExistingName = "a"; @@ -444,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); string folder1ExistingName = "a"; diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index 733ad25..90b6481 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -65,8 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, config, m_iam); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, config, m_iam); // Create user string userFirstName = "Jock"; @@ -86,10 +86,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests // log4net.Config.XmlConfigurator.Configure(); // Create asset - SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20); object1.AbsolutePosition = new Vector3(15, 30, 45); - SceneObjectGroup object2 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40); + SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40); object2.AbsolutePosition = new Vector3(25, 50, 75); CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2); @@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests // log4net.Config.XmlConfigurator.Configure(); // Create asset - SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40); UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 6ba3459..645113f 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -68,8 +68,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); } private void LoadCompleted(Guid requestId, string errorMessage) @@ -524,8 +524,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); + Scene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index a3aa38d..fecbf67 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -64,8 +64,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests { m_pcm = new PrimCountModule(); LandManagementModule lmm = new LandManagementModule(); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, lmm, m_pcm); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm); int xParcelDivider = (int)Constants.RegionSize - 1; @@ -111,7 +111,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); + SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); m_scene.AddNewSceneObject(sog, false); Assert.That(pc.Owner, Is.EqualTo(3)); @@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests Assert.That(pc.Simulator, Is.EqualTo(3)); // Add a second object and retest - SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, "b", 0x10); + SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10); m_scene.AddNewSceneObject(sog2, false); Assert.That(pc.Owner, Is.EqualTo(5)); @@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); + SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); m_scene.AddNewSceneObject(sog, false); m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity); @@ -172,9 +172,9 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); + SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); m_scene.AddNewSceneObject(sog, false); - SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, "b", 0x10); + SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10); m_scene.AddNewSceneObject(sog2, false); // Move the first scene object to the eastern strip parcel @@ -235,8 +235,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false); - SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, "b", 0x10); + m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false); + SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10); m_scene.AddNewSceneObject(sogToDelete, false); m_scene.DeleteSceneObject(sogToDelete, false); @@ -260,7 +260,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); + SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); sog.GroupID = m_groupId; m_scene.AddNewSceneObject(sog, false); @@ -291,11 +291,11 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - SceneObjectGroup sogToKeep = SceneSetupHelpers.CreateSceneObject(1, m_userId, "a", 0x1); + SceneObjectGroup sogToKeep = SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1); sogToKeep.GroupID = m_groupId; m_scene.AddNewSceneObject(sogToKeep, false); - SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, "b", 0x10); + SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10); m_scene.AddNewSceneObject(sogToDelete, false); m_scene.DeleteSceneObject(sogToDelete, false); @@ -318,7 +318,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); + SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); m_scene.AddNewSceneObject(sog, false); Assert.That(pc.Owner, Is.EqualTo(0)); @@ -339,8 +339,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests IPrimCounts pc = m_lo.PrimCounts; - m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false); - SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10); + m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false); + SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10); m_scene.AddNewSceneObject(sogToDelete, false); m_scene.DeleteSceneObject(sogToDelete, false); @@ -363,7 +363,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests TestHelper.InMethod(); IPrimCounts pc = m_lo.PrimCounts; - SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); + SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); m_scene.AddNewSceneObject(sog, false); m_pcm.TaintPrimCount(); diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index d5b7082..fe09739 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -53,8 +53,8 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests public void SetUp() { m_module = new MoapModule(); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, m_module); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, m_module); } [Test] @@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); MediaEntry me = new MediaEntry(); m_module.SetMediaEntry(part, 1, me); @@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests string homeUrl = "opensimulator.org"; - SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); MediaEntry me = new MediaEntry() { HomeURL = homeUrl }; m_module.SetMediaEntry(part, 1, me); diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index 4f752ab..93e38f8 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs @@ -236,8 +236,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests public void Init() { m_serialiserModule = new SerialiserModule(); - m_scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(m_scene, m_serialiserModule); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs index 5586c65..85197db 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs @@ -64,14 +64,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelper.InMethod(); - scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); + scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); interregionComms.Initialise(new IniConfigSource()); interregionComms.PostInitialise(); - SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); agent1 = UUID.Random(); random = new Random(); @@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests region1 = scene.RegionInfo.RegionHandle; region2 = scene2.RegionInfo.RegionHandle; - SceneSetupHelpers.AddClient(scene, agent1); + SceneHelpers.AddClient(scene, agent1); } [Test] @@ -126,8 +126,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests presence2.AddAttachment(sog2); ISharedRegionModule serialiser = new SerialiserModule(); - SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser); - SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser); + SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser); + SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser); Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index f69a4b4..ebf595a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs @@ -45,7 +45,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { static public Random random; SceneObjectGroup found; - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); [Test] public void T010_AddObjects() diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index 895f2bb..b7ff1b1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestDuplicateObject() { TestHelper.InMethod(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); string part1Name = "part1"; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 260d1c0..8b4771b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelper.InMethod(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); string objName = "obj1"; UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); @@ -78,7 +78,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelper.InMethod(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); string obj1Name = "Alfred"; string obj2Name = "Betty"; @@ -112,8 +112,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelper.InMethod(); - TestScene scene = SceneSetupHelpers.SetupScene(); - SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); + TestScene scene = SceneHelpers.SetupScene(); + SceneObjectPart part = SceneHelpers.AddSceneObject(scene); scene.DeleteSceneObject(part.ParentGroup, false); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); @@ -131,15 +131,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; sogd.Enabled = false; - SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(scene); - IClientAPI client = SceneSetupHelpers.AddClient(scene, agentId); + IClientAPI client = SceneHelpers.AddClient(scene, agentId); scene.DeRezObjects(client, new System.Collections.Generic.List() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index 1b8c100..d201510 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -61,12 +61,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); - SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); - TestClient client = SceneSetupHelpers.AddClient(scene, userId); + SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); + TestClient client = SceneHelpers.AddClient(scene, userId); // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; @@ -100,12 +100,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); - SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); - TestClient client = SceneSetupHelpers.AddClient(scene, userId); + SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); + TestClient client = SceneHelpers.AddClient(scene, userId); // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index cb1d531..b09144d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -54,10 +54,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests bool debugtest = false; - Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); + Scene scene = SceneHelpers.SetupScene(); + SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp1 = part1.ParentGroup; - SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); + SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp2 = part2.ParentGroup; grp1.AbsolutePosition = new Vector3(10, 10, 10); @@ -136,14 +136,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests bool debugtest = false; - Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); + Scene scene = SceneHelpers.SetupScene(); + SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp1 = part1.ParentGroup; - SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); + SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp2 = part2.ParentGroup; - SceneObjectPart part3 = SceneSetupHelpers.AddSceneObject(scene); + SceneObjectPart part3 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp3 = part3.ParentGroup; - SceneObjectPart part4 = SceneSetupHelpers.AddSceneObject(scene); + SceneObjectPart part4 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp4 = part4.ParentGroup; grp1.AbsolutePosition = new Vector3(10, 10, 10); @@ -269,7 +269,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); string rootPartName = "rootpart"; UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); @@ -308,7 +308,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); string rootPartName = "rootpart"; UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index c4047ee..8630476 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -52,8 +52,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectGroup g1 = SceneSetupHelpers.AddSceneObject(scene).ParentGroup; + Scene scene = SceneHelpers.SetupScene(); + SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup; g1.GroupResize(new Vector3(2, 3, 4)); @@ -75,9 +75,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); - SceneObjectGroup g1 = SceneSetupHelpers.CreateSceneObject(2, UUID.Zero); + SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero); g1.RootPart.Scale = new Vector3(2, 3, 4); g1.Parts[1].Scale = new Vector3(5, 6, 7); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index c0fca5d..c2adb2a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelper.InMethod(); // Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectGroup so = SceneSetupHelpers.CreateSceneObject(1, UUID.Zero); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); SceneObjectPart rootPart = so.RootPart; Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index 8425d37..e0ab1c8 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig startupConfig = configSource.AddConfig("Startup"); @@ -69,13 +69,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests groupsConfig.Set("Module", "GroupsModule"); groupsConfig.Set("DebugEnabled", true); - SceneSetupHelpers.SetupSceneModules( + SceneHelpers.SetupSceneModules( scene, configSource, new object[] { new PermissionsModule(), new GroupsModule(), new MockGroupsServicesConnector() }); - TestClient client = SceneSetupHelpers.AddClient(scene, userId); + TestClient client = SceneHelpers.AddClient(scene, userId); IGroupsModule groupsModule = scene.RequestModuleInterface(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs index a37b338..8af1b38 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs @@ -66,16 +66,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelper.InMethod(); - scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); - scene3 = SceneSetupHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); + scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); + scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); interregionComms.Initialise(new IniConfigSource()); interregionComms.PostInitialise(); - SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); - SceneSetupHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); agent1 = UUID.Random(); agent2 = UUID.Random(); @@ -203,16 +203,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); - TestScene myScene1 = SceneSetupHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); - TestScene myScene2 = SceneSetupHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); + TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); + TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); IConfigSource configSource = new IniConfigSource(); configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule"); EntityTransferModule etm = new EntityTransferModule(); - SceneSetupHelpers.SetupSceneModules(myScene1, configSource, etm); + SceneHelpers.SetupSceneModules(myScene1, configSource, etm); - SceneSetupHelpers.AddClient(myScene1, agent1Id); + SceneHelpers.AddClient(myScene1, agent1Id); ScenePresence childPresence = myScene2.GetScenePresence(agent1); // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 13d93f9..8ffb22e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -60,7 +60,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelper.InMethod(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); scene.Update(); Assert.That(scene.Frame, Is.EqualTo(1)); diff --git a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs index 4074f5d..a3848a7 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs @@ -116,16 +116,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - Scene sceneB = SceneSetupHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); - SceneSetupHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); + Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); + SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); sceneB.RegisterRegionWithGrid(); - Scene sceneA = SceneSetupHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); - SceneSetupHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); + Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); + SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); sceneA.RegisterRegionWithGrid(); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); - TestClient client = SceneSetupHelpers.AddClient(sceneA, agentId); + TestClient client = SceneHelpers.AddClient(sceneA, agentId); ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index f4e14d4..a61832a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -58,9 +58,9 @@ namespace OpenSim.Region.Framework.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); + SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; // Create an object embedded inside the first @@ -101,9 +101,9 @@ namespace OpenSim.Region.Framework.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); + SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); @@ -128,9 +128,9 @@ namespace OpenSim.Region.Framework.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); + SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index abca792..f6e2827 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); @@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); InventoryFolderBase folder1 diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index 4da8df1..b0ea497 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void Init() { // FIXME: We don't need a full scene here - it would be enough to set up the asset service. - Scene scene = SceneSetupHelpers.SetupScene(); + Scene scene = SceneHelpers.SetupScene(); m_assetService = scene.AssetService; m_uuidGatherer = new UuidGatherer(m_assetService); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index ee52a39..1e56a08 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -50,13 +50,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Groups"); config.Set("Enabled", true); config.Set("Module", "GroupsModule"); config.Set("DebugEnabled", true); - SceneSetupHelpers.SetupSceneModules( + SceneHelpers.SetupSceneModules( scene, configSource, new object[] { new MockGroupsServicesConnector() }); } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index c9dddba..c0053c9 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -57,9 +57,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests config.Configs["NPC"].Set("Enabled", "true"); AvatarFactoryModule afm = new AvatarFactoryModule(); - TestScene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); - TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); + TestScene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); + TestClient originalClient = SceneHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance @@ -94,9 +94,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests config.AddConfig("NPC"); config.Configs["NPC"].Set("Enabled", "true"); - TestScene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule()); - TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); + TestScene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, config, new NPCModule()); + TestClient originalClient = SceneHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); Vector3 startPos = new Vector3(128, 128, 30); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 80b60a4..3f37ec7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -57,8 +57,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); - Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); + Scene scene = SceneHelpers.SetupScene(); + SceneObjectPart part = SceneHelpers.AddSceneObject(scene); XEngine.XEngine engine = new XEngine.XEngine(); engine.Initialise(initConfigSource); -- cgit v1.1 From dad1d6df181151ae45fb998447b58d5589459627 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 00:31:03 +0100 Subject: rename TestHelper => TestHelpers for consistency --- .../CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | 12 ++++++------ .../AvatarFactory/Tests/AvatarFactoryModuleTests.cs | 6 +++--- .../Inventory/Archiver/Tests/InventoryArchiverTests.cs | 14 +++++++------- .../Avatar/Inventory/Archiver/Tests/PathTests.cs | 14 +++++++------- .../Tests/InventoryAccessModuleTests.cs | 4 ++-- .../CoreModules/World/Archiver/Tests/ArchiverTests.cs | 10 +++++----- .../World/Land/Tests/PrimCountModuleTests.cs | 18 +++++++++--------- .../CoreModules/World/Media/Moap/Tests/MoapTests.cs | 4 ++-- .../World/Serialiser/Tests/SerialiserTests.cs | 8 ++++---- .../Region/Framework/Scenes/Tests/AttachmentTests.cs | 8 ++++---- OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs | 8 ++++---- .../Framework/Scenes/Tests/EntityManagerTests.cs | 4 ++-- .../Region/Framework/Scenes/Tests/SceneGraphTests.cs | 2 +- .../Framework/Scenes/Tests/SceneObjectBasicTests.cs | 8 ++++---- .../Framework/Scenes/Tests/SceneObjectDeRezTests.cs | 4 ++-- .../Framework/Scenes/Tests/SceneObjectLinkingTests.cs | 8 ++++---- .../Framework/Scenes/Tests/SceneObjectResizeTests.cs | 4 ++-- .../Framework/Scenes/Tests/SceneObjectStatusTests.cs | 2 +- .../Scenes/Tests/SceneObjectUserGroupTests.cs | 2 +- .../Framework/Scenes/Tests/ScenePresenceTests.cs | 14 +++++++------- OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs | 2 +- .../Framework/Scenes/Tests/StandaloneTeleportTests.cs | 2 +- .../Framework/Scenes/Tests/TaskInventoryTests.cs | 6 +++--- .../Framework/Scenes/Tests/UserInventoryTests.cs | 4 ++-- .../Region/Framework/Scenes/Tests/UuidGathererTests.cs | 4 ++-- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 2 +- .../OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 10 +++++----- 27 files changed, 92 insertions(+), 92 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 1662f19..2ff1920 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs @@ -72,11 +72,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests [Test] public void TestCacheAsset() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); AssetBase asset = AssetHelpers.CreateAsset(); - asset.ID = TestHelper.ParseTail(0x1).ToString(); + asset.ID = TestHelpers.ParseTail(0x1).ToString(); // Check we don't get anything before the asset is put in the cache AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString()); @@ -93,11 +93,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests [Test] public void TestExpireAsset() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); AssetBase asset = AssetHelpers.CreateAsset(); - asset.ID = TestHelper.ParseTail(0x2).ToString(); + asset.ID = TestHelpers.ParseTail(0x2).ToString(); m_cache.Store(asset); @@ -110,11 +110,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests [Test] public void TestClearCache() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); AssetBase asset = AssetHelpers.CreateAsset(); - asset.ID = TestHelper.ParseTail(0x2).ToString(); + asset.ID = TestHelpers.ParseTail(0x2).ToString(); m_cache.Store(asset); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index c05f5ab..4e83fa7 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -44,10 +44,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory [Test] public void TestSetAppearance() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelper.ParseTail(0x1); + UUID userId = TestHelpers.ParseTail(0x1); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(); @@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; - afm.SetAppearance(tc, new Primitive.TextureEntry(TestHelper.ParseTail(0x10)), visualParams); + afm.SetAppearance(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); ScenePresence sp = scene.GetScenePresence(userId); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 3616ae2..e409c8e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadCoalesecedItem() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); @@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestOrder() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); @@ -129,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestSaveItemToIar() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); // Create user @@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestSaveItemToIarNoAssets() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); // Create user @@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadIarCreatorAccountPresent() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); @@ -357,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadIarV0_1SameNameCreator() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); @@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadIarV0_1AbsentCreator() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 1d3e5d0..417c20c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs @@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestSavePathToIarV0_1() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); InventoryArchiverModule archiverModule = new InventoryArchiverModule(); @@ -172,7 +172,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadIarToInventoryPaths() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SerialiserModule serialiserModule = new SerialiserModule(); @@ -217,7 +217,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadIarPathStartsWithSlash() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SerialiserModule serialiserModule = new SerialiserModule(); @@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestLoadIarPathWithEscapedChars() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); string itemName = "You & you are a mean/man/"; @@ -323,7 +323,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestNewIarPath() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); @@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestPartExistingIarPath() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); @@ -441,7 +441,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests [Test] public void TestMergeIarPath() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index 90b6481..e74310c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -82,7 +82,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests [Test] public void TestRezCoalescedObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); // Create asset @@ -138,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests [Test] public void TestRezObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); // Create asset diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 645113f..b185d9b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -125,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests [Test] public void TestSaveOar() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SceneObjectPart part1 = CreateSceneObjectPart1(); @@ -217,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests [Test] public void TestSaveOarNoAssets() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SceneObjectPart part1 = CreateSceneObjectPart1(); @@ -300,7 +300,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests [Test] public void TestLoadOar() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); MemoryStream archiveWriteStream = new MemoryStream(); @@ -409,7 +409,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests [Test] public void TestLoadOarRegionSettings() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); MemoryStream archiveWriteStream = new MemoryStream(); @@ -505,7 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests //[Test] public void TestMergeOar() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //XmlConfigurator.Configure(); MemoryStream archiveWriteStream = new MemoryStream(); diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index fecbf67..e553ffa 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestAddOwnerObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IPrimCounts pc = m_lo.PrimCounts; @@ -143,7 +143,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestCopyOwnerObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IPrimCounts pc = m_lo.PrimCounts; @@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestMoveOwnerObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); @@ -230,7 +230,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestRemoveOwnerObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IPrimCounts pc = m_lo.PrimCounts; @@ -253,7 +253,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestAddGroupObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); m_lo.DeedToGroup(m_groupId); @@ -284,7 +284,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestRemoveGroupObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); m_lo.DeedToGroup(m_groupId); @@ -313,7 +313,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestAddOthersObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IPrimCounts pc = m_lo.PrimCounts; @@ -334,7 +334,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestRemoveOthersObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IPrimCounts pc = m_lo.PrimCounts; @@ -360,7 +360,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests [Test] public void TestTaint() { - TestHelper.InMethod(); + TestHelpers.InMethod(); IPrimCounts pc = m_lo.PrimCounts; SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index fe09739..4326606 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -60,7 +60,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests [Test] public void TestClearMediaUrl() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); @@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests [Test] public void TestSetMediaUrl() { - TestHelper.InMethod(); + TestHelpers.InMethod(); string homeUrl = "opensimulator.org"; diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index 93e38f8..d5b585a 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs @@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests [Test] public void TestDeserializeXml() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml); @@ -259,7 +259,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests [Test] public void TestSerializeXml() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); string rpName = "My Little Donkey"; @@ -334,7 +334,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests [Test] public void TestDeserializeXml2() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(xml2); @@ -350,7 +350,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests [Test] public void TestSerializeXml2() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); string rpName = "My Little Pony"; diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs index 85197db..fb28397 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs @@ -62,7 +62,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixtureSetUp] public void Init() { - TestHelper.InMethod(); + TestHelpers.InMethod(); scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); @@ -89,7 +89,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T030_TestAddAttachments() { - TestHelper.InMethod(); + TestHelpers.InMethod(); ScenePresence presence = scene.GetScenePresence(agent1); @@ -104,7 +104,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T031_RemoveAttachments() { - TestHelper.InMethod(); + TestHelpers.InMethod(); ScenePresence presence = scene.GetScenePresence(agent1); presence.RemoveAttachment(sog1); @@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests //[Test] public void T032_CrossAttachments() { - TestHelper.InMethod(); + TestHelpers.InMethod(); ScenePresence presence = scene.GetScenePresence(agent1); ScenePresence presence2 = scene2.GetScenePresence(agent1); diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs index 3a0dd00..ab6311b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs @@ -41,7 +41,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestCross() { - TestHelper.InMethod(); + TestHelpers.InMethod(); List testborders = new List(); @@ -99,7 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestCrossSquare512() { - TestHelper.InMethod(); + TestHelpers.InMethod(); List testborders = new List(); @@ -179,7 +179,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestCrossRectangle512x256() { - TestHelper.InMethod(); + TestHelpers.InMethod(); List testborders = new List(); @@ -259,7 +259,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestCrossOdd512x512w256hole() { - TestHelper.InMethod(); + TestHelpers.InMethod(); List testborders = new List(); // 512____ diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index ebf595a..a5d2b23 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T010_AddObjects() { - TestHelper.InMethod(); + TestHelpers.InMethod(); random = new Random(); SceneObjectGroup found; @@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T011_ThreadAddRemoveTest() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // This test adds and removes with mutiple threads, attempting to break the // uuid and localid dictionary coherence. diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index b7ff1b1..9a60e50 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs @@ -43,7 +43,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestDuplicateObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); Scene scene = SceneHelpers.SetupScene(); UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 8b4771b..ff55680 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestAddSceneObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); Scene scene = SceneHelpers.SetupScene(); @@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// public void TestAddExistingSceneObjectUuid() { - TestHelper.InMethod(); + TestHelpers.InMethod(); Scene scene = SceneHelpers.SetupScene(); @@ -110,7 +110,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestDeleteSceneObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); TestScene scene = SceneHelpers.SetupScene(); SceneObjectPart part = SceneHelpers.AddSceneObject(scene); @@ -126,7 +126,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestDeleteSceneObjectAsync() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index d201510..c8a9ca3 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -56,7 +56,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestDeRezSceneObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); @@ -94,7 +94,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestDeRezSceneObjectNotOwner() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index b09144d..2912a46 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestLinkDelink2SceneObjects() { - TestHelper.InMethod(); + TestHelpers.InMethod(); bool debugtest = false; @@ -132,7 +132,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestLinkDelink2groups4SceneObjects() { - TestHelper.InMethod(); + TestHelpers.InMethod(); bool debugtest = false; @@ -266,7 +266,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestNewSceneObjectLinkPersistence() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); TestScene scene = SceneHelpers.SetupScene(); @@ -305,7 +305,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestDelinkPersistence() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); TestScene scene = SceneHelpers.SetupScene(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 8630476..b49c6e7 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestResizeSceneObject() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); @@ -72,7 +72,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestResizeSceneObjectPart() { - TestHelper.InMethod(); + TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index c2adb2a..2a342d5 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -46,7 +46,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestSetPhantom() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // Scene scene = SceneSetupHelpers.SetupScene(); SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index e0ab1c8..e604885 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs @@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestShareWithGroup() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs index 8af1b38..9b5f52f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixtureSetUp] public void Init() { - TestHelper.InMethod(); + TestHelpers.InMethod(); scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); @@ -97,7 +97,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T010_TestAddRootAgent() { - TestHelper.InMethod(); + TestHelpers.InMethod(); string firstName = "testfirstname"; @@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T011_TestRemoveRootAgent() { - TestHelper.InMethod(); + TestHelpers.InMethod(); scene.RemoveClient(agent1); @@ -147,7 +147,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T012_TestAddNeighbourRegion() { - TestHelper.InMethod(); + TestHelpers.InMethod(); string reason; @@ -175,7 +175,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void T013_TestRemoveNeighbourRegion() { - TestHelper.InMethod(); + TestHelpers.InMethod(); ScenePresence presence = scene.GetScenePresence(agent1); presence.RemoveNeighbourRegion(region3); @@ -198,7 +198,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestChildAgentEstablished() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); @@ -230,7 +230,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests //[Test] public void T021_TestCrossToNewRegion() { - TestHelper.InMethod(); + TestHelpers.InMethod(); scene.RegisterRegionWithGrid(); scene2.RegisterRegionWithGrid(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 8ffb22e..8b8aea5 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestUpdateScene() { - TestHelper.InMethod(); + TestHelpers.InMethod(); Scene scene = SceneHelpers.SetupScene(); scene.Update(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs index a3848a7..fb5a19f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests //[Test, LongRunning] public void TestSimpleNotNeighboursTeleport() { - TestHelper.InMethod(); + TestHelpers.InMethod(); ThreadRunResults results = new ThreadRunResults(); results.Result = false; results.Message = "Test did not run"; diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index a61832a..1abef8d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Tests [Test] public void TestRezObjectFromInventoryItem() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); @@ -98,7 +98,7 @@ namespace OpenSim.Region.Framework.Tests [Test] public void TestMoveTaskInventoryItem() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); @@ -125,7 +125,7 @@ namespace OpenSim.Region.Framework.Tests [Test] public void TestMoveTaskInventoryItemNoParent() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index f6e2827..50b1a48 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Tests [Test] public void TestGiveInventoryItem() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); @@ -82,7 +82,7 @@ namespace OpenSim.Region.Framework.Tests [Test] public void TestGiveInventoryFolder() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index b0ea497..24de56e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestCorruptAsset() { - TestHelper.InMethod(); + TestHelpers.InMethod(); UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); AssetBase corruptAsset @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [Test] public void TestMissingAsset() { - TestHelper.InMethod(); + TestHelpers.InMethod(); UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); IDictionary foundAssetUuids = new Dictionary(); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 1e56a08..d2f6327 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests [Test] public void TestBasic() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); TestScene scene = SceneHelpers.SetupScene(); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index c0053c9..28fa8a2 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests [Test] public void TestCreate() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IConfigSource config = new IniConfigSource(); @@ -59,11 +59,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); - TestClient originalClient = SceneHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); + TestClient originalClient = SceneHelpers.AddClient(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance - UUID originalFace8TextureId = TestHelper.ParseTail(0x10); + UUID originalFace8TextureId = TestHelpers.ParseTail(0x10); Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); originalTef.TextureID = originalFace8TextureId; @@ -86,7 +86,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests [Test] public void TestMove() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IConfigSource config = new IniConfigSource(); @@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, config, new NPCModule()); - TestClient originalClient = SceneHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); + TestClient originalClient = SceneHelpers.AddClient(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); Vector3 startPos = new Vector3(128, 128, 30); -- cgit v1.1 From 76f46b25454c0c9376130a59cc1b766c0d105dd0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 01:15:49 +0100 Subject: Do proper locking of m_localScenes list in SceneManager --- OpenSim/Region/Framework/Scenes/SceneManager.cs | 233 ++++++++++++++---------- 1 file changed, 140 insertions(+), 93 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 86ba2aa..069367d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -47,12 +47,12 @@ namespace OpenSim.Region.Framework.Scenes public event RestartSim OnRestartSim; - private readonly List m_localScenes; + private readonly List m_localScenes = new List(); private Scene m_currentScene = null; public List Scenes { - get { return m_localScenes; } + get { return new List(m_localScenes); } } public Scene CurrentScene @@ -66,13 +66,12 @@ namespace OpenSim.Region.Framework.Scenes { if (m_currentScene == null) { - if (m_localScenes.Count > 0) + lock (m_localScenes) { - return m_localScenes[0]; - } - else - { - return null; + if (m_localScenes.Count > 0) + return m_localScenes[0]; + else + return null; } } else @@ -82,26 +81,25 @@ namespace OpenSim.Region.Framework.Scenes } } - public SceneManager() - { - m_localScenes = new List(); - } - public void Close() { // collect known shared modules in sharedModules Dictionary sharedModules = new Dictionary(); - for (int i = 0; i < m_localScenes.Count; i++) + + lock (m_localScenes) { - // extract known shared modules from scene - foreach (string k in m_localScenes[i].Modules.Keys) + for (int i = 0; i < m_localScenes.Count; i++) { - if (m_localScenes[i].Modules[k].IsSharedModule && - !sharedModules.ContainsKey(k)) - sharedModules[k] = m_localScenes[i].Modules[k]; + // extract known shared modules from scene + foreach (string k in m_localScenes[i].Modules.Keys) + { + if (m_localScenes[i].Modules[k].IsSharedModule && + !sharedModules.ContainsKey(k)) + sharedModules[k] = m_localScenes[i].Modules[k]; + } + // close scene/region + m_localScenes[i].Close(); } - // close scene/region - m_localScenes[i].Close(); } // all regions/scenes are now closed, we can now safely @@ -114,13 +112,16 @@ namespace OpenSim.Region.Framework.Scenes public void Close(Scene cscene) { - if (m_localScenes.Contains(cscene)) + lock (m_localScenes) { - for (int i = 0; i < m_localScenes.Count; i++) + if (m_localScenes.Contains(cscene)) { - if (m_localScenes[i].Equals(cscene)) + for (int i = 0; i < m_localScenes.Count; i++) { - m_localScenes[i].Close(); + if (m_localScenes[i].Equals(cscene)) + { + m_localScenes[i].Close(); + } } } } @@ -129,27 +130,33 @@ namespace OpenSim.Region.Framework.Scenes public void Add(Scene scene) { scene.OnRestart += HandleRestart; - m_localScenes.Add(scene); + + lock (m_localScenes) + m_localScenes.Add(scene); } public void HandleRestart(RegionInfo rdata) { m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); int RegionSceneElement = -1; - for (int i = 0; i < m_localScenes.Count; i++) + + lock (m_localScenes) { - if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) + for (int i = 0; i < m_localScenes.Count; i++) { - RegionSceneElement = i; + if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) + { + RegionSceneElement = i; + } } - } - // Now we make sure the region is no longer known about by the SceneManager - // Prevents duplicates. + // Now we make sure the region is no longer known about by the SceneManager + // Prevents duplicates. - if (RegionSceneElement >= 0) - { - m_localScenes.RemoveAt(RegionSceneElement); + if (RegionSceneElement >= 0) + { + m_localScenes.RemoveAt(RegionSceneElement); + } } // Send signal to main that we're restarting this sim. @@ -160,28 +167,32 @@ namespace OpenSim.Region.Framework.Scenes { RegionInfo Result = null; - for (int i = 0; i < m_localScenes.Count; i++) - { - if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle) - { - // Inform other regions to tell their avatar about me - Result = m_localScenes[i].RegionInfo; - } - } - if (Result != null) + lock (m_localScenes) { for (int i = 0; i < m_localScenes.Count; i++) { - if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) + if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle) { // Inform other regions to tell their avatar about me - //m_localScenes[i].OtherRegionUp(Result); + Result = m_localScenes[i].RegionInfo; } } - } - else - { - m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); + + if (Result != null) + { + for (int i = 0; i < m_localScenes.Count; i++) + { + if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) + { + // Inform other regions to tell their avatar about me + //m_localScenes[i].OtherRegionUp(Result); + } + } + } + else + { + m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); + } } } @@ -285,7 +296,8 @@ namespace OpenSim.Region.Framework.Scenes { if (m_currentScene == null) { - m_localScenes.ForEach(func); + lock (m_localScenes) + m_localScenes.ForEach(func); } else { @@ -314,12 +326,15 @@ namespace OpenSim.Region.Framework.Scenes } else { - foreach (Scene scene in m_localScenes) + lock (m_localScenes) { - if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) + foreach (Scene scene in m_localScenes) { - m_currentScene = scene; - return true; + if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) + { + m_currentScene = scene; + return true; + } } } @@ -331,12 +346,15 @@ namespace OpenSim.Region.Framework.Scenes { m_log.Debug("Searching for Region: '" + regionID + "'"); - foreach (Scene scene in m_localScenes) + lock (m_localScenes) { - if (scene.RegionInfo.RegionID == regionID) + foreach (Scene scene in m_localScenes) { - m_currentScene = scene; - return true; + if (scene.RegionInfo.RegionID == regionID) + { + m_currentScene = scene; + return true; + } } } @@ -345,26 +363,33 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetScene(string regionName, out Scene scene) { - foreach (Scene mscene in m_localScenes) + lock (m_localScenes) { - if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) + foreach (Scene mscene in m_localScenes) { - scene = mscene; - return true; + if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) + { + scene = mscene; + return true; + } } } + scene = null; return false; } public bool TryGetScene(UUID regionID, out Scene scene) { - foreach (Scene mscene in m_localScenes) + lock (m_localScenes) { - if (mscene.RegionInfo.RegionID == regionID) + foreach (Scene mscene in m_localScenes) { - scene = mscene; - return true; + if (mscene.RegionInfo.RegionID == regionID) + { + scene = mscene; + return true; + } } } @@ -374,13 +399,16 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetScene(uint locX, uint locY, out Scene scene) { - foreach (Scene mscene in m_localScenes) + lock (m_localScenes) { - if (mscene.RegionInfo.RegionLocX == locX && - mscene.RegionInfo.RegionLocY == locY) + foreach (Scene mscene in m_localScenes) { - scene = mscene; - return true; + if (mscene.RegionInfo.RegionLocX == locX && + mscene.RegionInfo.RegionLocY == locY) + { + scene = mscene; + return true; + } } } @@ -390,13 +418,16 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) { - foreach (Scene mscene in m_localScenes) + lock (m_localScenes) { - if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && - (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port)) + foreach (Scene mscene in m_localScenes) { - scene = mscene; - return true; + if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && + (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port)) + { + scene = mscene; + return true; + } } } @@ -465,11 +496,14 @@ namespace OpenSim.Region.Framework.Scenes public RegionInfo GetRegionInfo(UUID regionID) { - foreach (Scene scene in m_localScenes) + lock (m_localScenes) { - if (scene.RegionInfo.RegionID == regionID) + foreach (Scene scene in m_localScenes) { - return scene.RegionInfo; + if (scene.RegionInfo.RegionID == regionID) + { + return scene.RegionInfo; + } } } @@ -488,11 +522,14 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) { - foreach (Scene scene in m_localScenes) + lock (m_localScenes) { - if (scene.TryGetScenePresence(avatarId, out avatar)) + foreach (Scene scene in m_localScenes) { - return true; + if (scene.TryGetScenePresence(avatarId, out avatar)) + { + return true; + } } } @@ -503,12 +540,16 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) { ScenePresence avatar = null; - foreach (Scene mScene in m_localScenes) + + lock (m_localScenes) { - if (mScene.TryGetScenePresence(avatarId, out avatar)) + foreach (Scene mScene in m_localScenes) { - scene = mScene; - return true; + if (mScene.TryGetScenePresence(avatarId, out avatar)) + { + scene = mScene; + return true; + } } } @@ -518,17 +559,22 @@ namespace OpenSim.Region.Framework.Scenes public void CloseScene(Scene scene) { - m_localScenes.Remove(scene); + lock (m_localScenes) + m_localScenes.Remove(scene); + scene.Close(); } public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) { - foreach (Scene scene in m_localScenes) + lock (m_localScenes) { - if (scene.TryGetAvatarByName(avatarName, out avatar)) + foreach (Scene scene in m_localScenes) { - return true; + if (scene.TryGetAvatarByName(avatarName, out avatar)) + { + return true; + } } } @@ -538,7 +584,8 @@ namespace OpenSim.Region.Framework.Scenes public void ForEachScene(Action action) { - m_localScenes.ForEach(action); + lock (m_localScenes) + m_localScenes.ForEach(action); } } -} +} \ No newline at end of file -- cgit v1.1 From 2b26d2f1a54686ed6a03efc26bf75002f80d42ee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 01:35:01 +0100 Subject: prevent "create region" console command from being able to create a region with the same id as one that already exists. Addresses http://opensimulator.org/mantis/view.php?id=5617 --- OpenSim/Region/Application/OpenSim.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 259d753..fe1525b 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -549,6 +549,7 @@ namespace OpenSim { string regionName = string.Empty; string regionFile = string.Empty; + if (cmd.Length == 3) { regionFile = cmd[2]; @@ -558,14 +559,17 @@ namespace OpenSim regionName = cmd[2]; regionFile = cmd[3]; } + string extension = Path.GetExtension(regionFile).ToLower(); bool isXml = extension.Equals(".xml"); bool isIni = extension.Equals(".ini"); + if (!isXml && !isIni) { MainConsole.Instance.Output("Usage: create region [\"region name\"] "); return; } + if (!Path.IsPathRooted(regionFile)) { string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim(); @@ -582,8 +586,18 @@ namespace OpenSim regInfo = new RegionInfo(regionName, regionFile, false, ConfigSource.Source, regionName); } - IScene scene; + Scene existingScene; + if (SceneManager.TryGetScene(regInfo.RegionID, out existingScene)) + { + MainConsole.Instance.OutputFormat( + "ERROR: Cannot create region {0} with ID {1}, this ID is already assigned to region {2}", + regInfo.RegionName, regInfo.RegionID, existingScene.RegionInfo.RegionName); + + return; + } + PopulateRegionEstateInfo(regInfo); + IScene scene; CreateRegion(regInfo, true, out scene); regInfo.EstateSettings.Save(); } -- cgit v1.1 From 83ba35a26bbbc844f4fd0f4964f3bc6155561e31 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 02:01:25 +0100 Subject: rip out sog generation methods in ScenePresenceAgentTests and use SceneHelpers instead Not that it matters, since these tests are pretty bogus anyway. Also, renames some test classes for consistency. --- .../Scenes/Tests/ScenePresenceAgentTests.cs | 355 +++++++++++++++++++ .../Scenes/Tests/ScenePresenceTeleportTests.cs | 196 +++++++++++ .../Framework/Scenes/Tests/ScenePresenceTests.cs | 385 --------------------- .../Scenes/Tests/StandaloneTeleportTests.cs | 196 ----------- 4 files changed, 551 insertions(+), 581 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs create mode 100644 OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs new file mode 100644 index 0000000..04f5817 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -0,0 +1,355 @@ +/* + * 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 System.Reflection; +using System.Text; +using System.Threading; +using System.Timers; +using Timer=System.Timers.Timer; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + /// + /// Scene presence tests + /// + [TestFixture] + public class ScenePresenceAgentTests + { + public Scene scene, scene2, scene3; + public UUID agent1, agent2, agent3; + public static Random random; + public ulong region1,region2,region3; + public AgentCircuitData acd1; + public SceneObjectGroup sog1, sog2, sog3; + public TestClient testclient; + + [TestFixtureSetUp] + public void Init() + { + TestHelpers.InMethod(); + + scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); + scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); + + ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); + interregionComms.Initialise(new IniConfigSource()); + interregionComms.PostInitialise(); + SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); + + agent1 = UUID.Random(); + agent2 = UUID.Random(); + agent3 = UUID.Random(); + random = new Random(); + sog1 = SceneHelpers.CreateSceneObject(1, agent1); + scene.AddSceneObject(sog1); + sog2 = SceneHelpers.CreateSceneObject(1, agent1); + scene.AddSceneObject(sog2); + sog3 = SceneHelpers.CreateSceneObject(1, agent1); + scene.AddSceneObject(sog3); + + region1 = scene.RegionInfo.RegionHandle; + region2 = scene2.RegionInfo.RegionHandle; + region3 = scene3.RegionInfo.RegionHandle; + } + + /// + /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene. + /// + [Test] + public void T010_TestAddRootAgent() + { + TestHelpers.InMethod(); + + string firstName = "testfirstname"; + + AgentCircuitData agent = new AgentCircuitData(); + agent.AgentID = agent1; + agent.firstname = firstName; + agent.lastname = "testlastname"; + agent.SessionID = UUID.Random(); + agent.SecureSessionID = UUID.Random(); + agent.circuitcode = 123; + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = Vector3.Zero; + agent.CapsPath = GetRandomCapsObjectPath(); + agent.ChildrenCapSeeds = new Dictionary(); + agent.child = true; + + scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); + + string reason; + scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); + testclient = new TestClient(agent, scene); + scene.AddNewClient(testclient); + + ScenePresence presence = scene.GetScenePresence(agent1); + + Assert.That(presence, Is.Not.Null, "presence is null"); + Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); + acd1 = agent; + } + + /// + /// Test removing an uncrossed root agent from a scene. + /// + [Test] + public void T011_TestRemoveRootAgent() + { + TestHelpers.InMethod(); + + scene.RemoveClient(agent1); + + ScenePresence presence = scene.GetScenePresence(agent1); + + Assert.That(presence, Is.Null, "presence is not null"); + } + + [Test] + public void T012_TestAddNeighbourRegion() + { + TestHelpers.InMethod(); + + string reason; + + if (acd1 == null) + fixNullPresence(); + + scene.NewUserConnection(acd1, 0, out reason); + if (testclient == null) + testclient = new TestClient(acd1, scene); + scene.AddNewClient(testclient); + + ScenePresence presence = scene.GetScenePresence(agent1); + presence.MakeRootAgent(new Vector3(90,90,90),false); + + string cap = presence.ControllingClient.RequestClientInfo().CapsPath; + + presence.AddNeighbourRegion(region2, cap); + presence.AddNeighbourRegion(region3, cap); + + List neighbours = presence.GetKnownRegionList(); + + Assert.That(neighbours.Count, Is.EqualTo(2)); + } + + [Test] + public void T013_TestRemoveNeighbourRegion() + { + TestHelpers.InMethod(); + + ScenePresence presence = scene.GetScenePresence(agent1); + presence.RemoveNeighbourRegion(region3); + + List neighbours = presence.GetKnownRegionList(); + Assert.That(neighbours.Count,Is.EqualTo(1)); + /* + presence.MakeChildAgent; + presence.MakeRootAgent; + CompleteAvatarMovement + */ + } + + /// + /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region + /// + /// + /// Please note that unlike the other tests here, this doesn't rely on structures + /// + [Test] + public void TestChildAgentEstablished() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); + + TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); + TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); + + IConfigSource configSource = new IniConfigSource(); + configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule"); + EntityTransferModule etm = new EntityTransferModule(); + + SceneHelpers.SetupSceneModules(myScene1, configSource, etm); + + SceneHelpers.AddClient(myScene1, agent1Id); + ScenePresence childPresence = myScene2.GetScenePresence(agent1); + + // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents +// Assert.That(childPresence, Is.Not.Null); +// Assert.That(childPresence.IsChildAgent, Is.True); + } + + // I'm commenting this test because it does not represent + // crossings. The Thread.Sleep's in here are not meaningful mocks, + // and they sometimes fail in panda. + // We need to talk in order to develop a test + // that really tests region crossings. There are 3 async components, + // but things are synchronous among them. So there should be + // 3 threads in here. + //[Test] + public void T021_TestCrossToNewRegion() + { + TestHelpers.InMethod(); + + scene.RegisterRegionWithGrid(); + scene2.RegisterRegionWithGrid(); + + // Adding child agent to region 1001 + string reason; + scene2.NewUserConnection(acd1,0, out reason); + scene2.AddNewClient(testclient); + + ScenePresence presence = scene.GetScenePresence(agent1); + presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); + + ScenePresence presence2 = scene2.GetScenePresence(agent1); + + // Adding neighbour region caps info to presence2 + + string cap = presence.ControllingClient.RequestClientInfo().CapsPath; + presence2.AddNeighbourRegion(region1, cap); + + Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); + Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); + + // Cross to x+1 + presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); + presence.Update(); + + EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); + + // Mimicking communication between client and server, by waiting OK from client + // sent by TestClient.CrossRegion call. Originally, this is network comm. + if (!wh.WaitOne(5000,false)) + { + presence.Update(); + if (!wh.WaitOne(8000,false)) + throw new ArgumentException("1 - Timeout waiting for signal/variable."); + } + + // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which + // would normally be fired after receiving the reply packet from comm. done on the last line. + testclient.CompleteMovement(); + + // Crossings are asynchronous + int timer = 10; + + // Make sure cross hasn't already finished + if (!presence.IsInTransit && !presence.IsChildAgent) + { + // If not and not in transit yet, give it some more time + Thread.Sleep(5000); + } + + // Enough time, should at least be in transit by now. + while (presence.IsInTransit && timer > 0) + { + Thread.Sleep(1000); + timer-=1; + } + + Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); + Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); + Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); + + // Cross Back + presence2.AbsolutePosition = new Vector3(-10, 3, 100); + presence2.Update(); + + if (!wh.WaitOne(5000,false)) + { + presence2.Update(); + if (!wh.WaitOne(8000,false)) + throw new ArgumentException("2 - Timeout waiting for signal/variable."); + } + testclient.CompleteMovement(); + + if (!presence2.IsInTransit && !presence2.IsChildAgent) + { + // If not and not in transit yet, give it some more time + Thread.Sleep(5000); + } + + // Enough time, should at least be in transit by now. + while (presence2.IsInTransit && timer > 0) + { + Thread.Sleep(1000); + timer-=1; + } + + Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); + Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); + Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); + } + + public void fixNullPresence() + { + string firstName = "testfirstname"; + + AgentCircuitData agent = new AgentCircuitData(); + agent.AgentID = agent1; + agent.firstname = firstName; + agent.lastname = "testlastname"; + agent.SessionID = UUID.Zero; + agent.SecureSessionID = UUID.Zero; + agent.circuitcode = 123; + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = Vector3.Zero; + agent.CapsPath = GetRandomCapsObjectPath(); + + acd1 = agent; + } + + public static string GetRandomCapsObjectPath() + { + UUID caps = UUID.Random(); + string capsPath = caps.ToString(); + capsPath = capsPath.Remove(capsPath.Length - 4, 4); + return capsPath; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs new file mode 100644 index 0000000..4765a86 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -0,0 +1,196 @@ +/* + * 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.Reflection; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; +using System.Threading; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + /// + /// Teleport tests in a standalone OpenSim + /// + [TestFixture] + public class ScenePresenceTeleportTests + { + /// + /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. + /// + /// Does not yet do what is says on the tin. + /// Commenting for now + //[Test, LongRunning] + public void TestSimpleNotNeighboursTeleport() + { + TestHelpers.InMethod(); + ThreadRunResults results = new ThreadRunResults(); + results.Result = false; + results.Message = "Test did not run"; + TestRunning testClass = new TestRunning(results); + + Thread testThread = new Thread(testClass.run); + + try + { + // Seems kind of redundant to start a thread and then join it, however.. We need to protect against + // A thread abort exception in the simulator code. + testThread.Start(); + testThread.Join(); + } + catch (ThreadAbortException) + { + + } + Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); + // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); + } + + [TearDown] + public void TearDown() + { + try + { + if (MainServer.Instance != null) MainServer.Instance.Stop(); + } + catch (NullReferenceException) + { } + } + + } + + public class ThreadRunResults + { + public bool Result = false; + public string Message = string.Empty; + } + + public class TestRunning + { + public ThreadRunResults results; + public TestRunning(ThreadRunResults t) + { + results = t; + } + public void run(object o) + { + + //results.Result = true; + log4net.Config.XmlConfigurator.Configure(); + + UUID sceneAId = UUID.Parse("00000000-0000-0000-0000-000000000100"); + UUID sceneBId = UUID.Parse("00000000-0000-0000-0000-000000000200"); + + // shared module + ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); + + + Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); + SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); + sceneB.RegisterRegionWithGrid(); + + Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); + SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); + sceneA.RegisterRegionWithGrid(); + + UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); + TestClient client = SceneHelpers.AddClient(sceneA, agentId); + + ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface(); + + results.Result = (sceneACapsModule.GetCapsPath(agentId) == client.CapsSeedUrl); + + if (!results.Result) + { + results.Message = "Incorrect caps object path set up in sceneA"; + return; + } + + /* + Assert.That( + sceneACapsModule.GetCapsPath(agentId), + Is.EqualTo(client.CapsSeedUrl), + "Incorrect caps object path set up in sceneA"); + */ + // FIXME: This is a hack to get the test working - really the normal OpenSim mechanisms should be used. + + + client.TeleportTargetScene = sceneB; + client.Teleport(sceneB.RegionInfo.RegionHandle, new Vector3(100, 100, 100), new Vector3(40, 40, 40)); + + results.Result = (sceneB.GetScenePresence(agentId) != null); + if (!results.Result) + { + results.Message = "Client does not have an agent in sceneB"; + return; + } + + //Assert.That(sceneB.GetScenePresence(agentId), Is.Not.Null, "Client does not have an agent in sceneB"); + + //Assert.That(sceneA.GetScenePresence(agentId), Is.Null, "Client still had an agent in sceneA"); + + results.Result = (sceneA.GetScenePresence(agentId) == null); + if (!results.Result) + { + results.Message = "Client still had an agent in sceneA"; + return; + } + + ICapabilitiesModule sceneBCapsModule = sceneB.RequestModuleInterface(); + + + results.Result = ("http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + + "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/" == client.CapsSeedUrl); + if (!results.Result) + { + results.Message = "Incorrect caps object path set up in sceneB"; + return; + } + + // Temporary assertion - caps url construction should at least be doable through a method. + /* + Assert.That( + "http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/", + Is.EqualTo(client.CapsSeedUrl), + "Incorrect caps object path set up in sceneB"); + */ + // This assertion will currently fail since we don't remove the caps paths when no longer needed + //Assert.That(sceneACapsModule.GetCapsPath(agentId), Is.Null, "sceneA still had a caps object path"); + + // TODO: Check that more of everything is as it should be + + // TODO: test what happens if we try to teleport to a region that doesn't exist + } + } +} diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs deleted file mode 100644 index 9b5f52f..0000000 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs +++ /dev/null @@ -1,385 +0,0 @@ -/* - * 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 System.Reflection; -using System.Text; -using System.Threading; -using System.Timers; -using Timer=System.Timers.Timer; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.CoreModules.Framework.EntityTransfer; -using OpenSim.Region.CoreModules.World.Serialiser; -using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.Framework.Scenes.Tests -{ - /// - /// Scene presence tests - /// - [TestFixture] - public class ScenePresenceTests - { - public Scene scene, scene2, scene3; - public UUID agent1, agent2, agent3; - public static Random random; - public ulong region1,region2,region3; - public AgentCircuitData acd1; - public SceneObjectGroup sog1, sog2, sog3; - public TestClient testclient; - - [TestFixtureSetUp] - public void Init() - { - TestHelpers.InMethod(); - - scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); - scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); - - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - interregionComms.Initialise(new IniConfigSource()); - interregionComms.PostInitialise(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); - - agent1 = UUID.Random(); - agent2 = UUID.Random(); - agent3 = UUID.Random(); - random = new Random(); - sog1 = NewSOG(UUID.Random(), scene, agent1); - sog2 = NewSOG(UUID.Random(), scene, agent1); - sog3 = NewSOG(UUID.Random(), scene, agent1); - - //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - region1 = scene.RegionInfo.RegionHandle; - region2 = scene2.RegionInfo.RegionHandle; - region3 = scene3.RegionInfo.RegionHandle; - } - - /// - /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene. - /// - [Test] - public void T010_TestAddRootAgent() - { - TestHelpers.InMethod(); - - string firstName = "testfirstname"; - - AgentCircuitData agent = new AgentCircuitData(); - agent.AgentID = agent1; - agent.firstname = firstName; - agent.lastname = "testlastname"; - agent.SessionID = UUID.Random(); - agent.SecureSessionID = UUID.Random(); - agent.circuitcode = 123; - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = Vector3.Zero; - agent.CapsPath = GetRandomCapsObjectPath(); - agent.ChildrenCapSeeds = new Dictionary(); - agent.child = true; - - scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); - - string reason; - scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); - testclient = new TestClient(agent, scene); - scene.AddNewClient(testclient); - - ScenePresence presence = scene.GetScenePresence(agent1); - - Assert.That(presence, Is.Not.Null, "presence is null"); - Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); - acd1 = agent; - } - - /// - /// Test removing an uncrossed root agent from a scene. - /// - [Test] - public void T011_TestRemoveRootAgent() - { - TestHelpers.InMethod(); - - scene.RemoveClient(agent1); - - ScenePresence presence = scene.GetScenePresence(agent1); - - Assert.That(presence, Is.Null, "presence is not null"); - } - - [Test] - public void T012_TestAddNeighbourRegion() - { - TestHelpers.InMethod(); - - string reason; - - if (acd1 == null) - fixNullPresence(); - - scene.NewUserConnection(acd1, 0, out reason); - if (testclient == null) - testclient = new TestClient(acd1, scene); - scene.AddNewClient(testclient); - - ScenePresence presence = scene.GetScenePresence(agent1); - presence.MakeRootAgent(new Vector3(90,90,90),false); - - string cap = presence.ControllingClient.RequestClientInfo().CapsPath; - - presence.AddNeighbourRegion(region2, cap); - presence.AddNeighbourRegion(region3, cap); - - List neighbours = presence.GetKnownRegionList(); - - Assert.That(neighbours.Count, Is.EqualTo(2)); - } - - [Test] - public void T013_TestRemoveNeighbourRegion() - { - TestHelpers.InMethod(); - - ScenePresence presence = scene.GetScenePresence(agent1); - presence.RemoveNeighbourRegion(region3); - - List neighbours = presence.GetKnownRegionList(); - Assert.That(neighbours.Count,Is.EqualTo(1)); - /* - presence.MakeChildAgent; - presence.MakeRootAgent; - CompleteAvatarMovement - */ - } - - /// - /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region - /// - /// - /// Please note that unlike the other tests here, this doesn't rely on structures - /// - [Test] - public void TestChildAgentEstablished() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); - - TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); - TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); - - IConfigSource configSource = new IniConfigSource(); - configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule"); - EntityTransferModule etm = new EntityTransferModule(); - - SceneHelpers.SetupSceneModules(myScene1, configSource, etm); - - SceneHelpers.AddClient(myScene1, agent1Id); - ScenePresence childPresence = myScene2.GetScenePresence(agent1); - - // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents -// Assert.That(childPresence, Is.Not.Null); -// Assert.That(childPresence.IsChildAgent, Is.True); - } - - // I'm commenting this test because it does not represent - // crossings. The Thread.Sleep's in here are not meaningful mocks, - // and they sometimes fail in panda. - // We need to talk in order to develop a test - // that really tests region crossings. There are 3 async components, - // but things are synchronous among them. So there should be - // 3 threads in here. - //[Test] - public void T021_TestCrossToNewRegion() - { - TestHelpers.InMethod(); - - scene.RegisterRegionWithGrid(); - scene2.RegisterRegionWithGrid(); - - // Adding child agent to region 1001 - string reason; - scene2.NewUserConnection(acd1,0, out reason); - scene2.AddNewClient(testclient); - - ScenePresence presence = scene.GetScenePresence(agent1); - presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); - - ScenePresence presence2 = scene2.GetScenePresence(agent1); - - // Adding neighbour region caps info to presence2 - - string cap = presence.ControllingClient.RequestClientInfo().CapsPath; - presence2.AddNeighbourRegion(region1, cap); - - Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); - Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); - - // Cross to x+1 - presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); - presence.Update(); - - EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); - - // Mimicking communication between client and server, by waiting OK from client - // sent by TestClient.CrossRegion call. Originally, this is network comm. - if (!wh.WaitOne(5000,false)) - { - presence.Update(); - if (!wh.WaitOne(8000,false)) - throw new ArgumentException("1 - Timeout waiting for signal/variable."); - } - - // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which - // would normally be fired after receiving the reply packet from comm. done on the last line. - testclient.CompleteMovement(); - - // Crossings are asynchronous - int timer = 10; - - // Make sure cross hasn't already finished - if (!presence.IsInTransit && !presence.IsChildAgent) - { - // If not and not in transit yet, give it some more time - Thread.Sleep(5000); - } - - // Enough time, should at least be in transit by now. - while (presence.IsInTransit && timer > 0) - { - Thread.Sleep(1000); - timer-=1; - } - - Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); - Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); - Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); - - // Cross Back - presence2.AbsolutePosition = new Vector3(-10, 3, 100); - presence2.Update(); - - if (!wh.WaitOne(5000,false)) - { - presence2.Update(); - if (!wh.WaitOne(8000,false)) - throw new ArgumentException("2 - Timeout waiting for signal/variable."); - } - testclient.CompleteMovement(); - - if (!presence2.IsInTransit && !presence2.IsChildAgent) - { - // If not and not in transit yet, give it some more time - Thread.Sleep(5000); - } - - // Enough time, should at least be in transit by now. - while (presence2.IsInTransit && timer > 0) - { - Thread.Sleep(1000); - timer-=1; - } - - Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); - Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); - Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); - } - - public void fixNullPresence() - { - string firstName = "testfirstname"; - - AgentCircuitData agent = new AgentCircuitData(); - agent.AgentID = agent1; - agent.firstname = firstName; - agent.lastname = "testlastname"; - agent.SessionID = UUID.Zero; - agent.SecureSessionID = UUID.Zero; - agent.circuitcode = 123; - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = Vector3.Zero; - agent.CapsPath = GetRandomCapsObjectPath(); - - acd1 = agent; - } - - public static string GetRandomCapsObjectPath() - { - UUID caps = UUID.Random(); - string capsPath = caps.ToString(); - capsPath = capsPath.Remove(capsPath.Length - 4, 4); - return capsPath; - } - - private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent) - { - SceneObjectPart sop = new SceneObjectPart(); - sop.Name = RandomName(); - sop.Description = RandomName(); - sop.Text = RandomName(); - sop.SitName = RandomName(); - sop.TouchName = RandomName(); - sop.UUID = uuid; - sop.Shape = PrimitiveBaseShape.Default; - sop.Shape.State = 1; - sop.OwnerID = agent; - - SceneObjectGroup sog = new SceneObjectGroup(sop); - sog.SetScene(scene); - - return sog; - } - - private static string RandomName() - { - StringBuilder name = new StringBuilder(); - int size = random.Next(5,12); - char ch ; - for (int i=0; i - /// Teleport tests in a standalone OpenSim - /// - [TestFixture] - public class StandaloneTeleportTests - { - /// - /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. - /// - /// Does not yet do what is says on the tin. - /// Commenting for now - //[Test, LongRunning] - public void TestSimpleNotNeighboursTeleport() - { - TestHelpers.InMethod(); - ThreadRunResults results = new ThreadRunResults(); - results.Result = false; - results.Message = "Test did not run"; - TestRunning testClass = new TestRunning(results); - - Thread testThread = new Thread(testClass.run); - - try - { - // Seems kind of redundant to start a thread and then join it, however.. We need to protect against - // A thread abort exception in the simulator code. - testThread.Start(); - testThread.Join(); - } - catch (ThreadAbortException) - { - - } - Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); - // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); - } - - [TearDown] - public void TearDown() - { - try - { - if (MainServer.Instance != null) MainServer.Instance.Stop(); - } - catch (NullReferenceException) - { } - } - - } - - public class ThreadRunResults - { - public bool Result = false; - public string Message = string.Empty; - } - - public class TestRunning - { - public ThreadRunResults results; - public TestRunning(ThreadRunResults t) - { - results = t; - } - public void run(object o) - { - - //results.Result = true; - log4net.Config.XmlConfigurator.Configure(); - - UUID sceneAId = UUID.Parse("00000000-0000-0000-0000-000000000100"); - UUID sceneBId = UUID.Parse("00000000-0000-0000-0000-000000000200"); - - // shared module - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - - - Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); - SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); - sceneB.RegisterRegionWithGrid(); - - Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); - SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); - sceneA.RegisterRegionWithGrid(); - - UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); - TestClient client = SceneHelpers.AddClient(sceneA, agentId); - - ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface(); - - results.Result = (sceneACapsModule.GetCapsPath(agentId) == client.CapsSeedUrl); - - if (!results.Result) - { - results.Message = "Incorrect caps object path set up in sceneA"; - return; - } - - /* - Assert.That( - sceneACapsModule.GetCapsPath(agentId), - Is.EqualTo(client.CapsSeedUrl), - "Incorrect caps object path set up in sceneA"); - */ - // FIXME: This is a hack to get the test working - really the normal OpenSim mechanisms should be used. - - - client.TeleportTargetScene = sceneB; - client.Teleport(sceneB.RegionInfo.RegionHandle, new Vector3(100, 100, 100), new Vector3(40, 40, 40)); - - results.Result = (sceneB.GetScenePresence(agentId) != null); - if (!results.Result) - { - results.Message = "Client does not have an agent in sceneB"; - return; - } - - //Assert.That(sceneB.GetScenePresence(agentId), Is.Not.Null, "Client does not have an agent in sceneB"); - - //Assert.That(sceneA.GetScenePresence(agentId), Is.Null, "Client still had an agent in sceneA"); - - results.Result = (sceneA.GetScenePresence(agentId) == null); - if (!results.Result) - { - results.Message = "Client still had an agent in sceneA"; - return; - } - - ICapabilitiesModule sceneBCapsModule = sceneB.RequestModuleInterface(); - - - results.Result = ("http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + - "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/" == client.CapsSeedUrl); - if (!results.Result) - { - results.Message = "Incorrect caps object path set up in sceneB"; - return; - } - - // Temporary assertion - caps url construction should at least be doable through a method. - /* - Assert.That( - "http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/", - Is.EqualTo(client.CapsSeedUrl), - "Incorrect caps object path set up in sceneB"); - */ - // This assertion will currently fail since we don't remove the caps paths when no longer needed - //Assert.That(sceneACapsModule.GetCapsPath(agentId), Is.Null, "sceneA still had a caps object path"); - - // TODO: Check that more of everything is as it should be - - // TODO: test what happens if we try to teleport to a region that doesn't exist - } - } -} -- cgit v1.1 From 85e07c78fbed9e85c142c0f565c27015ad95769d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 02:17:41 +0100 Subject: refactor: Change SceneHelpers.AddClient() to AddScenePresence(). This seems to make more sense as we can get SP.ControllingClient --- .../Tests/AvatarFactoryModuleTests.cs | 2 +- .../Framework/Scenes/Tests/AttachmentTests.cs | 2 +- .../Scenes/Tests/SceneObjectBasicTests.cs | 2 +- .../Scenes/Tests/SceneObjectDeRezTests.cs | 4 +- .../Scenes/Tests/SceneObjectUserGroupTests.cs | 2 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 72 ++++++++++++---------- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 4 +- 8 files changed, 50 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 4e83fa7..1bd3b6e 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, afm); - TestClient tc = SceneHelpers.AddClient(scene, userId); + IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs index fb28397..07b30f4 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests region1 = scene.RegionInfo.RegionHandle; region2 = scene2.RegionInfo.RegionHandle; - SceneHelpers.AddClient(scene, agent1); + SceneHelpers.AddScenePresence(scene, agent1); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index ff55680..1ea2329 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -139,7 +139,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectPart part = SceneHelpers.AddSceneObject(scene); - IClientAPI client = SceneHelpers.AddClient(scene, agentId); + IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; scene.DeRezObjects(client, new System.Collections.Generic.List() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index c8a9ca3..654b1a2 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); - TestClient client = SceneHelpers.AddClient(scene, userId); + IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; @@ -105,7 +105,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); - TestClient client = SceneHelpers.AddClient(scene, userId); + IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index e604885..c13d82e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests new GroupsModule(), new MockGroupsServicesConnector() }); - TestClient client = SceneHelpers.AddClient(scene, userId); + IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; IGroupsModule groupsModule = scene.RequestModuleInterface(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 04f5817..73acf28 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -93,6 +93,47 @@ namespace OpenSim.Region.Framework.Scenes.Tests region3 = scene3.RegionInfo.RegionHandle; } +// [Test] +// public void TestLogout() +// { +// TestHelpers.InMethod(); +//// log4net.Config.XmlConfigurator.Configure(); +// +// TestScene scene = SceneHelpers.SetupScene(); +// SceneHelpers. +// } + + /// + /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region + /// + /// + /// Please note that unlike the other tests here, this doesn't rely on structures + /// + [Test] + public void TestChildAgentEstablished() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); + + TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); +// TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); + + IConfigSource configSource = new IniConfigSource(); + configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule"); + EntityTransferModule etm = new EntityTransferModule(); + + SceneHelpers.SetupSceneModules(myScene1, configSource, etm); + + SceneHelpers.AddScenePresence(myScene1, agent1Id); +// ScenePresence childPresence = myScene2.GetScenePresence(agent1); + + // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents +// Assert.That(childPresence, Is.Not.Null); +// Assert.That(childPresence.IsChildAgent, Is.True); + } + /// /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene. /// @@ -190,37 +231,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests CompleteAvatarMovement */ } - - /// - /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region - /// - /// - /// Please note that unlike the other tests here, this doesn't rely on structures - /// - [Test] - public void TestChildAgentEstablished() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); - - TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); - TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); - - IConfigSource configSource = new IniConfigSource(); - configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule"); - EntityTransferModule etm = new EntityTransferModule(); - - SceneHelpers.SetupSceneModules(myScene1, configSource, etm); - - SceneHelpers.AddClient(myScene1, agent1Id); - ScenePresence childPresence = myScene2.GetScenePresence(agent1); - - // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents -// Assert.That(childPresence, Is.Not.Null); -// Assert.That(childPresence.IsChildAgent, Is.True); - } // I'm commenting this test because it does not represent // crossings. The Thread.Sleep's in here are not meaningful mocks, diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 4765a86..39bb43a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -125,7 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests sceneA.RegisterRegionWithGrid(); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); - TestClient client = SceneHelpers.AddClient(sceneA, agentId); + TestClient client = (TestClient)SceneHelpers.AddScenePresence(sceneA, agentId).ControllingClient; ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface(); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 28fa8a2..a0260a5 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); - TestClient originalClient = SceneHelpers.AddClient(scene, TestHelpers.ParseTail(0x1)); + IClientAPI originalClient = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)).ControllingClient; // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance @@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, config, new NPCModule()); - TestClient originalClient = SceneHelpers.AddClient(scene, TestHelpers.ParseTail(0x1)); + IClientAPI originalClient = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)).ControllingClient; // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); Vector3 startPos = new Vector3(128, 128, 30); -- cgit v1.1 From e37f8cf90270ba6e1605bdb528ca205a35cfe049 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 02:27:25 +0100 Subject: Add a test to check that ScenePresence and circuit go away when a root agent is closed down --- .../Scenes/Tests/ScenePresenceAgentTests.cs | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 73acf28..6cf905a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -93,15 +93,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests region3 = scene3.RegionInfo.RegionHandle; } -// [Test] -// public void TestLogout() -// { -// TestHelpers.InMethod(); -//// log4net.Config.XmlConfigurator.Configure(); -// -// TestScene scene = SceneHelpers.SetupScene(); -// SceneHelpers. -// } + [Test] + public void TestCloseAgent() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestScene scene = SceneHelpers.SetupScene(); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); + + Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null); + + scene.IncomingCloseAgent(sp.UUID); + + Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); + Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); + } /// /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region @@ -118,7 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); -// TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); +// TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); IConfigSource configSource = new IniConfigSource(); configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule"); -- cgit v1.1 From eec54adac5b6745c147ac7f7db947dba16e39d06 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 02:38:38 +0100 Subject: remove some obsolete tests that are now done elsewhere --- .../Scenes/Tests/ScenePresenceAgentTests.cs | 106 ++++++++++----------- 1 file changed, 53 insertions(+), 53 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 6cf905a..dd2c717 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -135,64 +135,64 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneHelpers.AddScenePresence(myScene1, agent1Id); // ScenePresence childPresence = myScene2.GetScenePresence(agent1); - + // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents // Assert.That(childPresence, Is.Not.Null); // Assert.That(childPresence.IsChildAgent, Is.True); } - /// - /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene. - /// - [Test] - public void T010_TestAddRootAgent() - { - TestHelpers.InMethod(); - - string firstName = "testfirstname"; - - AgentCircuitData agent = new AgentCircuitData(); - agent.AgentID = agent1; - agent.firstname = firstName; - agent.lastname = "testlastname"; - agent.SessionID = UUID.Random(); - agent.SecureSessionID = UUID.Random(); - agent.circuitcode = 123; - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = Vector3.Zero; - agent.CapsPath = GetRandomCapsObjectPath(); - agent.ChildrenCapSeeds = new Dictionary(); - agent.child = true; - - scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); - - string reason; - scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); - testclient = new TestClient(agent, scene); - scene.AddNewClient(testclient); - - ScenePresence presence = scene.GetScenePresence(agent1); - - Assert.That(presence, Is.Not.Null, "presence is null"); - Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); - acd1 = agent; - } - - /// - /// Test removing an uncrossed root agent from a scene. - /// - [Test] - public void T011_TestRemoveRootAgent() - { - TestHelpers.InMethod(); - - scene.RemoveClient(agent1); - - ScenePresence presence = scene.GetScenePresence(agent1); - - Assert.That(presence, Is.Null, "presence is not null"); - } +// /// +// /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene. +// /// +// [Test] +// public void T010_TestAddRootAgent() +// { +// TestHelpers.InMethod(); +// +// string firstName = "testfirstname"; +// +// AgentCircuitData agent = new AgentCircuitData(); +// agent.AgentID = agent1; +// agent.firstname = firstName; +// agent.lastname = "testlastname"; +// agent.SessionID = UUID.Random(); +// agent.SecureSessionID = UUID.Random(); +// agent.circuitcode = 123; +// agent.BaseFolder = UUID.Zero; +// agent.InventoryFolder = UUID.Zero; +// agent.startpos = Vector3.Zero; +// agent.CapsPath = GetRandomCapsObjectPath(); +// agent.ChildrenCapSeeds = new Dictionary(); +// agent.child = true; +// +// scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); +// +// string reason; +// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); +// testclient = new TestClient(agent, scene); +// scene.AddNewClient(testclient); +// +// ScenePresence presence = scene.GetScenePresence(agent1); +// +// Assert.That(presence, Is.Not.Null, "presence is null"); +// Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); +// acd1 = agent; +// } +// +// /// +// /// Test removing an uncrossed root agent from a scene. +// /// +// [Test] +// public void T011_TestRemoveRootAgent() +// { +// TestHelpers.InMethod(); +// +// scene.RemoveClient(agent1); +// +// ScenePresence presence = scene.GetScenePresence(agent1); +// +// Assert.That(presence, Is.Null, "presence is not null"); +// } [Test] public void T012_TestAddNeighbourRegion() -- cgit v1.1 From 6878049952ba25f853720d8f7fe0644569454c00 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 03:06:05 +0100 Subject: get rid of bogus log message --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ------- 1 file changed, 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d354c0a..cd5228d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2298,13 +2298,6 @@ namespace OpenSim.Region.Framework.Scenes /// The direction in which this avatar should now face. public void AddNewMovement(Vector3 vec, Quaternion rotation) { - if (m_isChildAgent) - { - // WHAT??? - m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); - return; - } - m_perfMonMS = Util.EnvironmentTickCount(); Rotation = rotation; -- cgit v1.1 From 78d8ce3816cde8702cfd4f5d198e2c69aff0a7be Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 8 Aug 2011 23:22:47 +0100 Subject: refactor: split out generic parts of osMakeNotecard() into a separate. Add method doc. Other minor tidies. --- .../Shared/Api/Implementation/OSSL_Api.cs | 157 +++++++++++++-------- 1 file changed, 99 insertions(+), 58 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 8093502..32ad21f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -348,20 +348,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api System.Threading.Thread.Sleep(delay); } - // - // OpenSim functions - // public LSL_Integer osSetTerrainHeight(int x, int y, double val) { CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight"); return SetTerrainHeight(x, y, val); } + public LSL_Integer osTerrainSetHeight(int x, int y, double val) { CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight"); OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); return SetTerrainHeight(x, y, val); } + private LSL_Integer SetTerrainHeight(int x, int y, double val) { m_host.AddScriptLPS(1); @@ -384,12 +383,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight"); return GetTerrainHeight(x, y); } + public LSL_Float osTerrainGetHeight(int x, int y) { CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight"); OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight"); return GetTerrainHeight(x, y); } + private LSL_Float GetTerrainHeight(int x, int y) { m_host.AddScriptLPS(1); @@ -1021,6 +1022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api drawList += "PenColor " + color + "; "; return drawList; } + // Deprecated public string osSetPenColour(string drawList, string colour) { @@ -1182,11 +1184,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api OSSLDeprecated("osSunGetParam", "osGetSunParam"); return GetSunParam(param); } + public double osGetSunParam(string param) { CheckThreatLevel(ThreatLevel.None, "osGetSunParam"); return GetSunParam(param); } + private double GetSunParam(string param) { m_host.AddScriptLPS(1); @@ -1208,11 +1212,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api OSSLDeprecated("osSunSetParam", "osSetSunParam"); SetSunParam(param, value); } + public void osSetSunParam(string param, double value) { CheckThreatLevel(ThreatLevel.None, "osSetSunParam"); SetSunParam(param, value); } + private void SetSunParam(string param, double value) { m_host.AddScriptLPS(1); @@ -1222,10 +1228,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { module.SetSunParameter(param, value); } - } - public string osWindActiveModelPluginName() { CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName"); @@ -1304,12 +1308,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api OSSLDeprecated(functionName, "osSetParcelDetails"); SetParcelDetails(pos, rules, functionName); } + public void osSetParcelDetails(LSL_Vector pos, LSL_List rules) { const string functionName = "osSetParcelDetails"; CheckThreatLevel(ThreatLevel.High, functionName); SetParcelDetails(pos, rules, functionName); } + private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName) { m_host.AddScriptLPS(1); @@ -1429,8 +1435,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID); else OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); - - } public string osGetScriptEngineName() @@ -1683,8 +1687,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return jsondata; } - // send a message to to object identified by the given UUID, a script in the object must implement the dataserver function - // the dataserver function is passed the ID of the calling function and a string message + /// + /// Send a message to to object identified by the given UUID + /// + /// + /// A script in the object must implement the dataserver function + /// the dataserver function is passed the ID of the calling function and a string message + /// + /// + /// public void osMessageObject(LSL_Key objectUUID, string message) { CheckThreatLevel(ThreatLevel.Low, "osMessageObject"); @@ -1699,24 +1710,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api "dataserver", resobj, new DetectParams[0])); } - - // This needs ThreatLevel high. It is an excellent griefer tool, - // In a loop, it can cause asset bloat and DOS levels of asset - // writes. - // + /// + /// Write a notecard directly to the prim's inventory. + /// + /// + /// This needs ThreatLevel high. It is an excellent griefer tool, + /// In a loop, it can cause asset bloat and DOS levels of asset + /// writes. + /// + /// The name of the notecard to write. + /// The contents of the notecard. public void osMakeNotecard(string notecardName, LSL_Types.list contents) { CheckThreatLevel(ThreatLevel.High, "osMakeNotecard"); m_host.AddScriptLPS(1); + StringBuilder notecardData = new StringBuilder(); + + for (int i = 0; i < contents.Length; i++) + notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n")); + + SaveNotecard(notecardName, notecardData.ToString()); + } + + protected void SaveNotecard(string notecardName, string notecardData) + { // Create new asset AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString()); asset.Description = "Script Generated Notecard"; - string notecardData = String.Empty; - - for (int i = 0; i < contents.Length; i++) { - notecardData += contents.GetLSLStringItem(i) + "\n"; - } int textLength = notecardData.Length; notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " @@ -1726,7 +1747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api World.AssetService.Store(asset); // Create Task Entry - TaskInventoryItem taskItem=new TaskInventoryItem(); + TaskInventoryItem taskItem = new TaskInventoryItem(); taskItem.ResetIDs(m_host.UUID); taskItem.ParentID = m_host.UUID; @@ -1751,13 +1772,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.Inventory.AddInventoryItem(taskItem, false); } - - /*Instead of using the LSL Dataserver event to pull notecard data, - this will simply read the requested line and return its data as a string. - - Warning - due to the synchronous method this function uses to fetch assets, its use - may be dangerous and unreliable while running in grid mode. - */ + /// + /// Directly get an entire notecard at once. + /// + /// + /// Instead of using the LSL Dataserver event to pull notecard data + /// this will simply read the entire notecard and return its data as a string. + /// + /// Warning - due to the synchronous method this function uses to fetch assets, its use + /// may be dangerous and unreliable while running in grid mode. + /// + /// Name of the notecard or its asset id + /// The line number to read. The first line is line 0 + /// Notecard line public string osGetNotecardLine(string name, int line) { CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine"); @@ -1799,17 +1826,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api }; return NotecardCache.GetLine(assetID, line, 255); - - } - /*Instead of using the LSL Dataserver event to pull notecard data line by line, - this will simply read the entire notecard and return its data as a string. - - Warning - due to the synchronous method this function uses to fetch assets, its use - may be dangerous and unreliable while running in grid mode. - */ - + /// + /// Get an entire notecard at once. + /// + /// + /// Instead of using the LSL Dataserver event to pull notecard data line by line, + /// this will simply read the entire notecard and return its data as a string. + /// + /// Warning - due to the synchronous method this function uses to fetch assets, its use + /// may be dangerous and unreliable while running in grid mode. + /// + /// Name of the notecard or its asset id + /// Notecard text public string osGetNotecard(string name) { CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard"); @@ -1857,17 +1887,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } return NotecardData; - - } - /*Instead of using the LSL Dataserver event to pull notecard data, - this will simply read the number of note card lines and return this data as an integer. - - Warning - due to the synchronous method this function uses to fetch assets, its use - may be dangerous and unreliable while running in grid mode. - */ - + /// + /// Get the number of lines in the given notecard. + /// + /// + /// Instead of using the LSL Dataserver event to pull notecard data, + /// this will simply read the number of note card lines and return this data as an integer. + /// + /// Warning - due to the synchronous method this function uses to fetch assets, its use + /// may be dangerous and unreliable while running in grid mode. + /// + /// Name of the notecard or its asset id + /// public int osGetNumberOfNotecardLines(string name) { CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines"); @@ -1947,15 +1980,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { return ""; } - } + /// + /// Get the nickname of this grid, as set in the [GridInfo] config section. + /// + /// /// Threat level is Moderate because intentional abuse, for instance /// scripts that are written to be malicious only on one grid, /// for instance in a HG scenario, are a distinct possibility. - /// - /// Use value from the config file and return it. - /// + /// + /// public string osGetGridNick() { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); @@ -2063,12 +2098,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return World.RegionInfo.RegionSettings.LoadedCreationID; } - // Threat level is 'Low' because certain users could possibly be tricked into - // dropping an unverified script into one of their own objects, which could - // then gather the physical construction details of the object and transmit it - // to an unscrupulous third party, thus permitting unauthorized duplication of - // the object's form. - // + /// + /// Get the primitive parameters of a linked prim. + /// + /// + /// Threat level is 'Low' because certain users could possibly be tricked into + /// dropping an unverified script into one of their own objects, which could + /// then gather the physical construction details of the object and transmit it + /// to an unscrupulous third party, thus permitting unauthorized duplication of + /// the object's form. + /// + /// + /// + /// public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) { CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); @@ -2344,10 +2386,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api obj.Shape.ProjectionFocus = (float)focus; obj.Shape.ProjectionAmbiance = (float)amb; - obj.ParentGroup.HasGroupChanged = true; obj.ScheduleFullUpdate(); - } /// @@ -2372,6 +2412,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } }); + return result; } @@ -2391,4 +2432,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); } } -} +} \ No newline at end of file -- cgit v1.1 From 3e16a0fbdd9477f24a93e0e70311bfca7995e339 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 9 Aug 2011 00:12:41 +0100 Subject: factor out common notecard caching code from 3 methods. --- .../Shared/Api/Implementation/OSSL_Api.cs | 167 +++++++++------------ 1 file changed, 74 insertions(+), 93 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 32ad21f..154179c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1733,7 +1733,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SaveNotecard(notecardName, notecardData.ToString()); } - protected void SaveNotecard(string notecardName, string notecardData) + /// + /// Save a notecard to prim inventory. + /// + /// + /// + /// Prim inventory item created. + protected TaskInventoryItem SaveNotecard(string notecardName, string notecardData) { // Create new asset AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString()); @@ -1770,6 +1776,66 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api taskItem.AssetID = asset.FullID; m_host.Inventory.AddInventoryItem(taskItem, false); + + return taskItem; + } + + /// + /// Load the notecard data found at the given prim inventory item name or asset uuid. + /// + /// + /// The text loaded. Null if no notecard was found. + protected string LoadNotecard(string notecardNameOrUuid) + { + UUID assetID = CacheNotecard(notecardNameOrUuid); + StringBuilder notecardData = new StringBuilder(); + + for (int count = 0; count < NotecardCache.GetLines(assetID); count++) + notecardData.Append(NotecardCache.GetLine(assetID, count, 255) + "\n"); + + return notecardData.ToString(); + } + + /// + /// Cache a notecard's contents. + /// + /// + /// + /// The asset id of the notecard, which is used for retrieving the cached data. + /// UUID.Zero if no asset could be found. + /// + protected UUID CacheNotecard(string notecardNameOrUuid) + { + UUID assetID = UUID.Zero; + StringBuilder notecardData = new StringBuilder(); + + if (!UUID.TryParse(notecardNameOrUuid, out assetID)) + { + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + { + if (item.Type == 7 && item.Name == notecardNameOrUuid) + { + assetID = item.AssetID; + } + } + } + + if (assetID == UUID.Zero) + return UUID.Zero; + + if (!NotecardCache.IsCached(assetID)) + { + AssetBase a = World.AssetService.Get(assetID.ToString()); + + if (a == null) + return UUID.Zero; + + System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); + string data = enc.GetString(a.Data); + NotecardCache.Cache(assetID, data); + }; + + return assetID; } /// @@ -1790,18 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine"); m_host.AddScriptLPS(1); - UUID assetID = UUID.Zero; - - if (!UUID.TryParse(name, out assetID)) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 7 && item.Name == name) - { - assetID = item.AssetID; - } - } - } + UUID assetID = CacheNotecard(name); if (assetID == UUID.Zero) { @@ -1809,22 +1864,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return "ERROR!"; } - if (!NotecardCache.IsCached(assetID)) - { - AssetBase a = World.AssetService.Get(assetID.ToString()); - if (a != null) - { - System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); - string data = enc.GetString(a.Data); - NotecardCache.Cache(assetID, data); - } - else - { - OSSLShoutError("Notecard '" + name + "' could not be found."); - return "ERROR!"; - } - }; - return NotecardCache.GetLine(assetID, line, 255); } @@ -1845,48 +1884,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard"); m_host.AddScriptLPS(1); - UUID assetID = UUID.Zero; - string NotecardData = ""; - - if (!UUID.TryParse(name, out assetID)) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 7 && item.Name == name) - { - assetID = item.AssetID; - } - } - } + string text = LoadNotecard(name); - if (assetID == UUID.Zero) + if (text == null) { OSSLShoutError("Notecard '" + name + "' could not be found."); return "ERROR!"; } - - if (!NotecardCache.IsCached(assetID)) - { - AssetBase a = World.AssetService.Get(assetID.ToString()); - if (a != null) - { - System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); - string data = enc.GetString(a.Data); - NotecardCache.Cache(assetID, data); - } - else - { - OSSLShoutError("Notecard '" + name + "' could not be found."); - return "ERROR!"; - } - }; - - for (int count = 0; count < NotecardCache.GetLines(assetID); count++) + else { - NotecardData += NotecardCache.GetLine(assetID, count, 255) + "\n"; + return text; } - - return NotecardData; } /// @@ -1906,18 +1914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines"); m_host.AddScriptLPS(1); - UUID assetID = UUID.Zero; - - if (!UUID.TryParse(name, out assetID)) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 7 && item.Name == name) - { - assetID = item.AssetID; - } - } - } + UUID assetID = CacheNotecard(name); if (assetID == UUID.Zero) { @@ -1925,22 +1922,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return -1; } - if (!NotecardCache.IsCached(assetID)) - { - AssetBase a = World.AssetService.Get(assetID.ToString()); - if (a != null) - { - System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); - string data = enc.GetString(a.Data); - NotecardCache.Cache(assetID, data); - } - else - { - OSSLShoutError("Notecard '" + name + "' could not be found."); - return -1; - } - }; - return NotecardCache.GetLines(assetID); } @@ -2412,7 +2393,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } }); - + return result; } -- cgit v1.1 From e869eeb0bfc48c769f680970f99e4c67dd5a1a70 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 9 Aug 2011 03:51:34 +0100 Subject: Implement first draft functions for saving and loading NPC appearance from storage. This works by serializing and deserializing NPC AvatarAppearance to a notecard in the prim inventory and making the required baked textures permanent. By using notecards, we avoid lots of awkward, technical and user-unfriendly issues concerning retaining asset references and creating a new asset type. Notecards also allow different appearances to be swapped and manipulated easily. This also allows stored NPC appearances to work transparently with OARs/IARs since the UUID scan will pick up and store the necessary references from the notecard text. This works in my basic test but is not at all ready for user use or bug reporting yet. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 87 ++++++++++++----- .../Tests/AvatarFactoryModuleTests.cs | 2 +- .../Region/Framework/Interfaces/IAvatarFactory.cs | 8 ++ OpenSim/Region/Framework/Interfaces/INPCModule.cs | 19 +++- .../Region/OptionalModules/World/NPC/NPCModule.cs | 29 ++++++ .../World/NPC/Tests/NPCModuleTests.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 33 +++++-- .../Shared/Api/Implementation/OSSL_Api.cs | 104 ++++++++++++++++++--- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 10 ++ 10 files changed, 251 insertions(+), 45 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index e3e3452..75d8143 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void NewClient(IClientAPI client) { client.OnRequestWearables += SendWearables; - client.OnSetAppearance += SetAppearance; + client.OnSetAppearance += SetAppearanceFromClient; client.OnAvatarNowWearing += AvatarIsWearing; } @@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// /// /// - public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) + public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) { ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) @@ -257,6 +257,47 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return true; } + public bool SaveBakedTextures(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + + if (sp == null || sp.IsChildAgent) + return false; + + AvatarAppearance appearance = sp.Appearance; + Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures; + + m_log.DebugFormat( + "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", + sp.Name, m_scene.RegionInfo.RegionName); + + for (int i = 0; i < faceTextures.Length; i++) + { +// m_log.DebugFormat( +// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", +// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); + + if (faceTextures[i] == null) + continue; + + AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString()); + + if (asset != null) + { + asset.Temporary = false; + m_scene.AssetService.Store(asset); + } + else + { + m_log.WarnFormat( + "[AV FACTORY]: Baked texture {0} for {1} in {2} unexpectedly not found when trying to save permanently", + faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName); + } + } + + return true; + } + #region UpdateAppearanceTimer /// @@ -289,25 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } - private void HandleAppearanceSend(UUID agentid) - { - ScenePresence sp = m_scene.GetScenePresence(agentid); - if (sp == null) - { - m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); - return; - } - - // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid); - - // Send the appearance to everyone in the scene - sp.SendAppearanceToAllOtherAgents(); - - // Send animations back to the avatar as well - sp.Animator.SendAnimPack(); - } - - private void HandleAppearanceSave(UUID agentid) + private void SaveAppearance(UUID agentid) { // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved // in a culture where decimal points are commas and then reloaded in a culture which just treats them as @@ -337,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { if (kvp.Value < now) { - Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); + Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); }); m_sendqueue.Remove(kvp.Key); } } @@ -350,7 +373,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { if (kvp.Value < now) { - Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); + Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); }); m_savequeue.Remove(kvp.Key); } } @@ -427,6 +450,24 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } + public bool SendAppearance(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + if (sp == null) + { + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); + return false; + } + + // Send the appearance to everyone in the scene + sp.SendAppearanceToAllOtherAgents(); + + // Send animations back to the avatar as well + sp.Animator.SendAnimPack(); + + return true; + } + private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) { IInventoryService invService = m_scene.InventoryService; diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 1bd3b6e..b831b31 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; - afm.SetAppearance(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); + afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); ScenePresence sp = scene.GetScenePresence(userId); diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs index d0e5609..6817725 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs @@ -32,6 +32,14 @@ namespace OpenSim.Region.Framework.Interfaces { public interface IAvatarFactory { + /// + /// Send the appearance of an avatar to others in the scene. + /// + /// + /// + bool SendAppearance(UUID agentId); + + bool SaveBakedTextures(UUID agentId); bool ValidateBakedTextureCache(IClientAPI client); void QueueAppearanceSend(UUID agentid); void QueueAppearanceSave(UUID agentid); diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index fa8d6b6..54575ca 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -26,6 +26,7 @@ */ using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces @@ -44,6 +45,23 @@ namespace OpenSim.Region.Framework.Interfaces UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); /// + /// Check if the agent is an NPC. + /// + /// + /// + /// True if the agent is an NPC in the given scene. False otherwise. + bool IsNPC(UUID agentID, Scene scene); + + /// + /// Set the appearance for an NPC. + /// + /// + /// + /// + /// + bool SetNPCAppearance(UUID agentID, AvatarAppearance appearance, Scene scene); + + /// /// Move an NPC to a target over time. /// /// The UUID of the NPC @@ -59,7 +77,6 @@ namespace OpenSim.Region.Framework.Interfaces /// void Say(UUID agentID, Scene scene, string text); - /// /// Delete an NPC. /// diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 4f21d9d..d966345 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -137,6 +137,35 @@ namespace OpenSim.Region.OptionalModules.World.NPC } } + public bool IsNPC(UUID agentId, Scene scene) + { + ScenePresence sp = scene.GetScenePresence(agentId); + if (sp == null || sp.IsChildAgent) + return false; + + lock (m_avatars) + return m_avatars.ContainsKey(agentId); + } + + public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene) + { + ScenePresence sp = scene.GetScenePresence(agentId); + if (sp == null || sp.IsChildAgent) + return false; + + lock (m_avatars) + if (!m_avatars.ContainsKey(agentId)) + return false; + + AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); + sp.Appearance = npcAppearance; + + IAvatarFactory module = scene.RequestModuleInterface(); + module.SendAppearance(sp.UUID); + + return true; + } + public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) { NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index a0260a5..2ec354f 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); - afm.SetAppearance(originalClient, originalTe, null); + afm.SetAppearanceFromClient(originalClient, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface(); UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7c21ba9..86ee28a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10565,9 +10565,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public static string GetLine(UUID assetID, int line, int maxLength) + /// + /// Get a notecard line. + /// + /// + /// Lines start at index 0 + /// + public static string GetLine(UUID assetID, int lineNumber) { - if (line < 0) + if (lineNumber < 0) return ""; string data; @@ -10579,17 +10585,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_Notecards[assetID].lastRef = DateTime.Now; - if (line >= m_Notecards[assetID].text.Length) + if (lineNumber >= m_Notecards[assetID].text.Length) return "\n\n\n"; - data = m_Notecards[assetID].text[line]; - if (data.Length > maxLength) - data = data.Substring(0, maxLength); + data = m_Notecards[assetID].text[lineNumber]; return data; } } + /// + /// Get a notecard line. + /// + /// + /// Lines start at index 0 + /// Maximum length of the returned line. Longer lines will be truncated + /// + public static string GetLine(UUID assetID, int lineNumber, int maxLength) + { + string line = GetLine(assetID, lineNumber); + + if (line.Length > maxLength) + line = line.Substring(0, maxLength); + + return line; + } + public static void CacheCheck() { foreach (UUID key in new List(m_Notecards.Keys)) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 154179c..07b36de 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -28,11 +28,16 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; +using System.Reflection; using System.Runtime.Remoting.Lifetime; using System.Text; using System.Net; using System.Threading; +using System.Xml; +using log4net; using OpenMetaverse; +using OpenMetaverse.StructuredData; using Nini.Config; using OpenSim; using OpenSim.Framework; @@ -119,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api [Serializable] public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + internal IScriptEngine m_ScriptEngine; internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there internal SceneObjectPart m_host; @@ -1730,26 +1737,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api for (int i = 0; i < contents.Length; i++) notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n")); - SaveNotecard(notecardName, notecardData.ToString()); + SaveNotecard(notecardName, "Script generated notecard", notecardData.ToString(), false); } /// /// Save a notecard to prim inventory. /// - /// + /// + /// Description of notecard /// + /// + /// If true, then if an item exists with the same name, it is replaced. + /// If false, then a new item is created witha slightly different name (e.g. name 1) + /// /// Prim inventory item created. - protected TaskInventoryItem SaveNotecard(string notecardName, string notecardData) + protected TaskInventoryItem SaveNotecard(string name, string description, string data, bool forceSameName) { // Create new asset - AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString()); - asset.Description = "Script Generated Notecard"; + AssetBase asset = new AssetBase(UUID.Random(), name, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString()); + asset.Description = description; - int textLength = notecardData.Length; - notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " - + textLength.ToString() + "\n" + notecardData + "}\n"; + int textLength = data.Length; + data + = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " + + textLength.ToString() + "\n" + data + "}\n"; - asset.Data = Util.UTF8.GetBytes(notecardData); + asset.Data = Util.UTF8.GetBytes(data); World.AssetService.Store(asset); // Create Task Entry @@ -1775,7 +1788,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api taskItem.PermsMask = 0; taskItem.AssetID = asset.FullID; - m_host.Inventory.AddInventoryItem(taskItem, false); + if (forceSameName) + m_host.Inventory.AddInventoryItemExclusive(taskItem, false); + else + m_host.Inventory.AddInventoryItem(taskItem, false); return taskItem; } @@ -1791,7 +1807,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api StringBuilder notecardData = new StringBuilder(); for (int count = 0; count < NotecardCache.GetLines(assetID); count++) - notecardData.Append(NotecardCache.GetLine(assetID, count, 255) + "\n"); + { + string line = NotecardCache.GetLine(assetID, count) + "\n"; + +// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line); + + notecardData.Append(line); + } return notecardData.ToString(); } @@ -1807,7 +1829,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID CacheNotecard(string notecardNameOrUuid) { UUID assetID = UUID.Zero; - StringBuilder notecardData = new StringBuilder(); if (!UUID.TryParse(notecardNameOrUuid, out assetID)) { @@ -1864,7 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return "ERROR!"; } - return NotecardCache.GetLine(assetID, line, 255); + return NotecardCache.GetLine(assetID, line); } /// @@ -2122,9 +2143,66 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Key(x.ToString()); } + return new LSL_Key(UUID.Zero.ToString()); } + public LSL_Key osNpcSaveAppearance(string avatar, string notecardName) + { + CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); + + INPCModule npcModule = World.RequestModuleInterface(); + IAvatarFactory appearanceModule = World.RequestModuleInterface(); + + if (npcModule != null && appearanceModule != null) + { + UUID avatarId = UUID.Zero; + if (!UUID.TryParse(avatar, out avatarId)) + return new LSL_Key(UUID.Zero.ToString()); + + if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) + return new LSL_Key(UUID.Zero.ToString()); + + appearanceModule.SaveBakedTextures(avatarId); + ScenePresence sp = m_host.ParentGroup.Scene.GetScenePresence(avatarId); + OSDMap appearancePacked = sp.Appearance.Pack(); + + TaskInventoryItem item + = SaveNotecard(notecardName, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); + + return new LSL_Key(item.AssetID.ToString()); + } + + return new LSL_Key(UUID.Zero.ToString()); + } + + public void osNpcLoadAppearance(string avatar, string notecardNameOrUuid) + { + CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); + + INPCModule npcModule = World.RequestModuleInterface(); + + if (npcModule != null) + { + UUID avatarId = UUID.Zero; + if (!UUID.TryParse(avatar, out avatarId)) + return; + + if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) + return; + + string appearanceSerialized = LoadNotecard(notecardNameOrUuid); + OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); +// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized); +// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized); +// Console.WriteLine("a.Type {0}, a.ToString() {1}", a.Type, a); + AvatarAppearance appearance = new AvatarAppearance(); + appearance.Unpack(appearanceOsd); + + npcModule.SetNPCAppearance(avatarId, appearance, m_host.ParentGroup.Scene); + } + } + public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 19352f0..868af27 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -170,6 +170,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces key osNpcCreate(string user, string name, vector position, key cloneFrom); + LSL_Key osNpcSaveAppearance(string avatar, string notecardName); + void osNpcLoadAppearance(string avatar, string notecardNameOrUuid); void osNpcMoveTo(key npc, vector position); void osNpcSay(key npc, string message); void osNpcRemove(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 7c59098..959b5d5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -483,6 +483,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); } + public key osNpcSaveAppearance(string avatar, string notecardName) + { + return m_OSSL_Functions.osNpcSaveAppearance(avatar, notecardName); + } + + public void osNpcLoadAppearance(string avatar, string notecardNameOrUuid) + { + m_OSSL_Functions.osNpcLoadAppearance(avatar, notecardNameOrUuid); + } + public void osNpcMoveTo(key npc, vector position) { m_OSSL_Functions.osNpcMoveTo(npc, position); -- cgit v1.1 From 795c8e6c22d4174d942ad56e70a0acbe507e2ec7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 9 Aug 2011 22:05:47 +0100 Subject: Add osOwnerSaveAppearance() to help with setting up NPC appearances. Not yet ready for user use. Adds regression test. --- .../Shared/Api/Implementation/OSSL_Api.cs | 51 ++++++++-- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 + .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 105 +++++++++++++++++++++ 4 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 07b36de..a05c623 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2147,14 +2147,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Key(UUID.Zero.ToString()); } + /// + /// Save the current appearance of the NPC permanently to the named notecard. + /// + /// + /// The name of the notecard to which to save the appearance. + /// The asset ID of the notecard saved. public LSL_Key osNpcSaveAppearance(string avatar, string notecardName) { CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); INPCModule npcModule = World.RequestModuleInterface(); - IAvatarFactory appearanceModule = World.RequestModuleInterface(); - if (npcModule != null && appearanceModule != null) + if (npcModule != null) { UUID avatarId = UUID.Zero; if (!UUID.TryParse(avatar, out avatarId)) @@ -2163,14 +2168,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) return new LSL_Key(UUID.Zero.ToString()); - appearanceModule.SaveBakedTextures(avatarId); - ScenePresence sp = m_host.ParentGroup.Scene.GetScenePresence(avatarId); - OSDMap appearancePacked = sp.Appearance.Pack(); - - TaskInventoryItem item - = SaveNotecard(notecardName, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); - - return new LSL_Key(item.AssetID.ToString()); + return SaveAppearanceToNotecard(avatarId, notecardName); } return new LSL_Key(UUID.Zero.ToString()); @@ -2236,6 +2234,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api module.DeleteNPC(new UUID(npc.m_string), World); } } + + /// + /// Save the current appearance of the script owner permanently to the named notecard. + /// + /// The name of the notecard to which to save the appearance. + /// The asset ID of the notecard saved. + public LSL_Key osOwnerSaveAppearance(string notecardName) + { + CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance"); + + return SaveAppearanceToNotecard(m_host.OwnerID, notecardName); + } + + protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecardName) + { + IAvatarFactory appearanceModule = World.RequestModuleInterface(); + + if (appearanceModule != null) + { + appearanceModule.SaveBakedTextures(m_host.OwnerID); + ScenePresence sp = m_host.ParentGroup.Scene.GetScenePresence(m_host.OwnerID); + OSDMap appearancePacked = sp.Appearance.Pack(); + + TaskInventoryItem item + = SaveNotecard(notecardName, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); + + return new LSL_Key(item.AssetID.ToString()); + } + else + { + return new LSL_Key(UUID.Zero.ToString()); + } + } /// /// Get current region's map texture UUID diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 868af27..92473ae 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -176,6 +176,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcSay(key npc, string message); void osNpcRemove(key npc); + LSL_Key osOwnerSaveAppearance(string notecardName); + key osGetMapTexture(); key osGetRegionMapTexture(string regionName); LSL_List osGetRegionStats(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 959b5d5..4b21c88 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -508,6 +508,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcRemove(npc); } + public LSL_Key osOwnerSaveAppearance(string notecardName) + { + return m_OSSL_Functions.osOwnerSaveAppearance(notecardName); + } + public OSSLPrim Prim; [Serializable] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs new file mode 100644 index 0000000..fc8b551 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -0,0 +1,105 @@ +/* + * 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 System.Text; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Avatar.AvatarFactory; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Tests +{ + /// + /// Tests for OSSL_Api + /// + [TestFixture] + public class OSSL_ApiAppearanceTest + { + [Test] + public void TestOsOwnerSaveAppearance() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + IConfigSource initConfigSource = new IniConfigSource(); + IConfig config = initConfigSource.AddConfig("XEngine"); + config.Set("Enabled", "true"); + config.Set("AllowOSFunctions", "true"); + config.Set("OSFunctionThreatLevel", "Severe"); + + UUID userId = TestHelpers.ParseTail(0x1); + float newHeight = 1.9f; + + Scene scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, new AvatarFactoryModule()); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); + sp.Appearance.AvatarHeight = newHeight; + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectPart part = so.RootPart; + scene.AddSceneObject(so); + + XEngine.XEngine engine = new XEngine.XEngine(); + engine.Initialise(initConfigSource); + engine.AddRegion(scene); + + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(engine, part, part.LocalId, part.UUID); + + string notecardName = "appearanceNc"; + + osslApi.osOwnerSaveAppearance(notecardName); + + IList items = part.Inventory.GetInventoryItems(notecardName); + Assert.That(items.Count, Is.EqualTo(1)); + + TaskInventoryItem ncItem = items[0]; + Assert.That(ncItem.Name, Is.EqualTo(notecardName)); + + AssetBase ncAsset = scene.AssetService.Get(ncItem.AssetID.ToString()); + Assert.That(ncAsset, Is.Not.Null); + + AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data); + anc.Decode(); + OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText); + AvatarAppearance savedAppearance = new AvatarAppearance(); + savedAppearance.Unpack(appearanceOsd); + + Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight)); + } + } +} \ No newline at end of file -- cgit v1.1 From 92e96d394a1712ed16b0a7835dd2ccfde01f3fee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 9 Aug 2011 23:11:07 +0100 Subject: When an NPC is created, stop telling neighbouring regions to expect a child agent --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 6 +++--- .../Framework/EntityTransfer/EntityTransferModule.cs | 6 +++++- OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++++++++---- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 4 ++-- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 8 ++------ OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 8 +------- 7 files changed, 23 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4a36b5d..46d7f78 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -90,7 +90,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ObjectAttach OnObjectAttach; public event ObjectDeselect OnObjectDetach; public event ObjectDrop OnObjectDrop; - public event GenericCall1 OnCompleteMovementToRegion; + public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; @@ -6195,10 +6195,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack) { - GenericCall1 handlerCompleteMovementToRegion = OnCompleteMovementToRegion; + Action handlerCompleteMovementToRegion = OnCompleteMovementToRegion; if (handlerCompleteMovementToRegion != null) { - handlerCompleteMovementToRegion(sender); + handlerCompleteMovementToRegion(sender, true); } handlerCompleteMovementToRegion = null; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 457ee33..f5d49c5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1065,10 +1065,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion #region Enable Child Agent + /// /// This informs a single neighbouring region about agent "avatar". /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// + /// + /// public void EnableChildAgent(ScenePresence sp, GridRegion region) { m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); @@ -1126,6 +1129,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// This informs all neighbouring regions about agent "avatar". /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// + /// public void EnableChildAgents(ScenePresence sp) { List neighbours = new List(); @@ -1312,7 +1316,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Utils.LongToUInts(reg.RegionHandle, out x, out y); x = x / Constants.RegionSize; y = y / Constants.RegionSize; - m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); + m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")"); string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 4f58ab0..08023b8 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event DeRezObject OnDeRezObject; public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; - public event GenericCall1 OnCompleteMovementToRegion; + public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; @@ -663,7 +663,7 @@ namespace OpenSim.Region.Examples.SimpleModule if (OnCompleteMovementToRegion != null) { - OnCompleteMovementToRegion(this); + OnCompleteMovementToRegion(this, true); } } public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cd5228d..af28dd9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1144,10 +1144,14 @@ namespace OpenSim.Region.Framework.Scenes /// /// Complete Avatar's movement into the region. - /// This is called upon a very important packet sent from the client, - /// so it's client-controlled. Never call this method directly. /// - public void CompleteMovement(IClientAPI client) + /// + /// + /// If true, send notification to neighbour regions to expect + /// a child agent from the client. These neighbours can be some distance away, depending right now on the + /// configuration of DefaultDrawDistance in the [Startup] section of config + /// + public void CompleteMovement(IClientAPI client, bool enableNeighbourChildAgents) { // DateTime startTime = DateTime.Now; @@ -1188,7 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes SendInitialData(); // Create child agents in neighbouring regions - if (!m_isChildAgent) + if (enableNeighbourChildAgents && !m_isChildAgent) { IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); if (m_agentTransfer != null) diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index a0c1ab1..8ebf9cb 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -677,7 +677,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event DeRezObject OnDeRezObject; public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; - public event GenericCall1 OnCompleteMovementToRegion; + public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; @@ -913,7 +913,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server if (OnCompleteMovementToRegion != null) { - OnCompleteMovementToRegion(this); + OnCompleteMovementToRegion(this, true); } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index dfc624d..b3e2495 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -190,7 +190,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event DeRezObject OnDeRezObject; public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; - public event GenericCall1 OnCompleteMovementToRegion; + public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; @@ -745,12 +745,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC { OnRegionHandShakeReply(this); } - - if (OnCompleteMovementToRegion != null) - { - OnCompleteMovementToRegion(this); - } } + public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) { } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index d966345..88867f2 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -201,13 +201,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_log.DebugFormat( "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID); - // Shouldn't call this - temporary. - sp.CompleteMovement(npcAvatar); - -// sp.SendAppearanceToAllOtherAgents(); -// -// // Send animations back to the avatar as well -// sp.Animator.SendAnimPack(); + sp.CompleteMovement(npcAvatar, false); } else { -- cgit v1.1 From cba54090c759d1b21701179493f8399eb1b7a60f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 9 Aug 2011 23:25:52 +0100 Subject: When an NPC appearance is loaded, rez the attachments too --- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 88867f2..068eec8 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -159,6 +159,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); sp.Appearance = npcAppearance; + sp.RezAttachments(); IAvatarFactory module = scene.RequestModuleInterface(); module.SendAppearance(sp.UUID); -- cgit v1.1 From 195c1dc9b8b8511980d9a607a242b24a5a91da17 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 10 Aug 2011 00:26:38 +0100 Subject: implement osNpcStopMoveTo() to cancel any current move target --- .../Avatar/Attachments/AttachmentsModule.cs | 4 +-- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 19 ++++++++--- .../Region/OptionalModules/World/NPC/NPCModule.cs | 37 ++++++++++++++++++++-- .../Shared/Api/Implementation/OSSL_Api.cs | 9 ++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++ 6 files changed, 66 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 1e09610..ebb5bd2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -566,8 +566,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { - m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, - attachmentpoint, attachOffset, so.RootPart.AttachedPos); + m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", + so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); so.DetachFromBackup(); diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 54575ca..763d2dc 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// - /// + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC bool SetNPCAppearance(UUID agentID, AvatarAppearance appearance, Scene scene); /// @@ -67,7 +67,16 @@ namespace OpenSim.Region.Framework.Interfaces /// The UUID of the NPC /// /// - void MoveToTarget(UUID agentID, Scene scene, Vector3 pos); + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos); + + /// + /// Stop the NPC's current movement. + /// + /// The UUID of the NPC + /// + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool StopMoveToTarget(UUID agentID, Scene scene); /// /// Get the NPC to say something. @@ -75,13 +84,15 @@ namespace OpenSim.Region.Framework.Interfaces /// The UUID of the NPC /// /// - void Say(UUID agentID, Scene scene, string text); + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool Say(UUID agentID, Scene scene, string text); /// /// Delete an NPC. /// /// The UUID of the NPC /// - void DeleteNPC(UUID agentID, Scene scene); + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool DeleteNPC(UUID agentID, Scene scene); } } \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 068eec8..87cb322 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -217,7 +217,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC return npcAvatar.AgentId; } - public void MoveToTarget(UUID agentID, Scene scene, Vector3 pos) + public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos) { lock (m_avatars) { @@ -230,22 +230,49 @@ namespace OpenSim.Region.OptionalModules.World.NPC "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); sp.MoveToTarget(pos); + + return true; + } + } + + return false; + } + + public bool StopMoveToTarget(UUID agentID, Scene scene) + { + lock (m_avatars) + { + if (m_avatars.ContainsKey(agentID)) + { + ScenePresence sp; + scene.TryGetScenePresence(agentID, out sp); + + sp.Velocity = Vector3.Zero; + sp.ResetMoveToTarget(); + + return true; } } + + return false; } - public void Say(UUID agentID, Scene scene, string text) + public bool Say(UUID agentID, Scene scene, string text) { lock (m_avatars) { if (m_avatars.ContainsKey(agentID)) { m_avatars[agentID].Say(text); + + return true; } } + + return false; } - public void DeleteNPC(UUID agentID, Scene scene) + public bool DeleteNPC(UUID agentID, Scene scene) { lock (m_avatars) { @@ -253,8 +280,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC { scene.RemoveClient(agentID); m_avatars.Remove(agentID); + + return true; } } + + return false; } public void PostInitialise() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index a05c623..9c32029 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2213,6 +2213,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public void osNpcStopMoveTo(LSL_Key npc) + { + CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); + + INPCModule module = World.RequestModuleInterface(); + if (module != null) + module.StopMoveToTarget(new UUID(npc.m_string), World); + } + public void osNpcSay(LSL_Key npc, string message) { CheckThreatLevel(ThreatLevel.High, "osNpcSay"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 92473ae..ab0097a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -173,6 +173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Key osNpcSaveAppearance(string avatar, string notecardName); void osNpcLoadAppearance(string avatar, string notecardNameOrUuid); void osNpcMoveTo(key npc, vector position); + void osNpcStopMoveTo(LSL_Key npc); void osNpcSay(key npc, string message); void osNpcRemove(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 4b21c88..a7843dd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -498,6 +498,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcMoveTo(npc, position); } + public void osNpcStopMoveTo(LSL_Key npc) + { + m_OSSL_Functions.osNpcStopMoveTo(npc); + } + public void osNpcSay(key npc, string message) { m_OSSL_Functions.osNpcSay(npc, message); -- cgit v1.1 From 4cb8d6379ddb39cfb8b30a63475e154a00a78110 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 10 Aug 2011 00:59:31 +0100 Subject: Stop trying to deregister caps or close child agents when an NPC is removed --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 15 +++++++-------- OpenSim/Region/Framework/Scenes/SceneBase.cs | 12 +----------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++--- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 5 files changed, 13 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 46d7f78..977918a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -512,7 +512,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpServer.Flush(m_udpClient); // Remove ourselves from the scene - m_scene.RemoveClient(AgentId); + m_scene.RemoveClient(AgentId, true); // We can't reach into other scenes and close the connection // We need to do this over grid communications diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b3b6cbc..9aa9bf5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3091,11 +3091,7 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Remove the given client from the scene. - /// - /// - public override void RemoveClient(UUID agentID) + public override void RemoveClient(UUID agentID, bool closeChildAgents) { CheckHeartbeat(); bool childagentYN = false; @@ -3116,15 +3112,17 @@ namespace OpenSim.Region.Framework.Scenes (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); m_sceneGraph.removeUserCount(!childagentYN); - - if (CapsModule != null) + + // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop + // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI + if (closeChildAgents && CapsModule != null) CapsModule.RemoveCaps(agentID); // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever // this method is doing is HORRIBLE!!! avatar.Scene.NeedSceneCacheClear(avatar.UUID); - if (!avatar.IsChildAgent) + if (closeChildAgents && !avatar.IsChildAgent) { //List childknownRegions = new List(); //List ckn = avatar.KnownChildRegionHandles; @@ -3136,6 +3134,7 @@ namespace OpenSim.Region.Framework.Scenes regions.Remove(RegionInfo.RegionHandle); m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); } + m_eventManager.TriggerClientClosed(agentID, this); } catch (NullReferenceException) diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index c4547f2..2f1cdc1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -175,18 +175,8 @@ namespace OpenSim.Region.Framework.Scenes #region Add/Remove Agent/Avatar - /// - /// Register the new client with the scene. The client starts off as a child agent - the later agent crossing - /// will promote it to a root agent during login. - /// - /// - /// Remove a client from the scene - /// - /// - public abstract void RemoveClient(UUID agentID); + public abstract void RemoveClient(UUID agentID, bool closeChildAgents); public bool TryGetScenePresence(UUID agentID, out object scenePresence) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index af28dd9..2db83eb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1146,12 +1146,12 @@ namespace OpenSim.Region.Framework.Scenes /// Complete Avatar's movement into the region. /// /// - /// + /// /// If true, send notification to neighbour regions to expect /// a child agent from the client. These neighbours can be some distance away, depending right now on the /// configuration of DefaultDrawDistance in the [Startup] section of config /// - public void CompleteMovement(IClientAPI client, bool enableNeighbourChildAgents) + public void CompleteMovement(IClientAPI client, bool openChildAgents) { // DateTime startTime = DateTime.Now; @@ -1192,7 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes SendInitialData(); // Create child agents in neighbouring regions - if (enableNeighbourChildAgents && !m_isChildAgent) + if (openChildAgents && !m_isChildAgent) { IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); if (m_agentTransfer != null) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 87cb322..7b9457a 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -278,7 +278,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { if (m_avatars.ContainsKey(agentID)) { - scene.RemoveClient(agentID); + scene.RemoveClient(agentID, false); m_avatars.Remove(agentID); return true; -- cgit v1.1 From 5d6c9644faf6aeac38410af9cff97adfef88d7aa Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 10 Aug 2011 01:47:37 +0100 Subject: early code to allow scripts to force npcs not to fly when moving to target this is to allow walking on prims. it will be up to the script writer to be sure that there is a continuous path. currently implemented in osNpcMoveToTarget(), but none of this is final. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 6 +++--- OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 6 +++++- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +++++++-- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 2 +- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 4 ++-- .../OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 4 ++-- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 14 +++++++++++++- .../Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++++ 12 files changed, 42 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 977918a..1d35973 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event Action OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; @@ -11628,9 +11628,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP locy = Convert.ToSingle(args[1]) - (float)regionY; locz = Convert.ToSingle(args[2]); - Action handlerAutoPilotGo = OnAutoPilotGo; + Action handlerAutoPilotGo = OnAutoPilotGo; if (handlerAutoPilotGo != null) - handlerAutoPilotGo(new Vector3(locx, locy, locz)); + handlerAutoPilotGo(new Vector3(locx, locy, locz), false); } /// diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 08023b8..c87790f 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event Action OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 763d2dc..06296c9 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -67,8 +67,12 @@ namespace OpenSim.Region.Framework.Interfaces /// The UUID of the NPC /// /// + /// + /// If true, then the avatar will attempt to walk to the location even if it's up in the air. + /// This is to allow walking on prims. + /// /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC - bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos); + bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly); /// /// Stop the NPC's current movement. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3b6a458..fe96152 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1650,7 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); if (avatar != null) { - avatar.MoveToTarget(target); + avatar.MoveToTarget(target, false); } } else diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2db83eb..b8e4e93 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1684,7 +1684,12 @@ namespace OpenSim.Region.Framework.Scenes /// Move to the given target over time. /// /// - public void MoveToTarget(Vector3 pos) + /// + /// If true, then don't allow the avatar to fly to the target, even if it's up in the air. + /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path + /// from start to finish. + /// + public void MoveToTarget(Vector3 pos, bool noFly) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", @@ -1718,7 +1723,7 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); - if (pos.Z > terrainHeight) + if (!noFly && pos.Z > terrainHeight) PhysicsActor.Flying = true; MovingToTarget = true; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 8ebf9cb..15201da 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event Action OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index b3e2495..cfd692d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event Action OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 7b9457a..d0b5a94 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -217,7 +217,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC return npcAvatar.AgentId; } - public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos) + public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly) { lock (m_avatars) { @@ -229,7 +229,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_log.DebugFormat( "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); - sp.MoveToTarget(pos); + sp.MoveToTarget(pos, noFly); return true; } diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 2ec354f..81497d5 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); Vector3 targetPos = startPos + new Vector3(0, 0, 10); - npcModule.MoveToTarget(npc.UUID, scene, targetPos); + npcModule.MoveToTarget(npc.UUID, scene, targetPos, false); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); @@ -135,7 +135,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // Try a second movement startPos = npc.AbsolutePosition; targetPos = startPos + new Vector3(10, 0, 0); - npcModule.MoveToTarget(npc.UUID, scene, targetPos); + npcModule.MoveToTarget(npc.UUID, scene, targetPos, false); scene.Update(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9c32029..63c882d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2209,7 +2209,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (module != null) { Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); - module.MoveToTarget(new UUID(npc.m_string), World, pos); + module.MoveToTarget(new UUID(npc.m_string), World, pos, false); + } + } + + public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector position, int noFly) + { + CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); + + INPCModule module = World.RequestModuleInterface(); + if (module != null) + { + Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); + module.MoveToTarget(new UUID(npc.m_string), World, pos, noFly != 0); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index ab0097a..56be9d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -173,6 +173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Key osNpcSaveAppearance(string avatar, string notecardName); void osNpcLoadAppearance(string avatar, string notecardNameOrUuid); void osNpcMoveTo(key npc, vector position); + void osNpcMoveToTarget(key npc, vector position, int noFly); void osNpcStopMoveTo(LSL_Key npc); void osNpcSay(key npc, string message); void osNpcRemove(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index a7843dd..c745e5c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -498,6 +498,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcMoveTo(npc, position); } + public void osNpcMoveToTarget(key npc, vector position, int noFly) + { + m_OSSL_Functions.osNpcMoveToTarget(npc, position, noFly); + } + public void osNpcStopMoveTo(LSL_Key npc) { m_OSSL_Functions.osNpcStopMoveTo(npc); -- cgit v1.1 From fb92678b83dca1c1f64cc91f3ac887170408a455 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 10 Aug 2011 22:34:42 +0100 Subject: fly and no fly constants for osNpcMoveToTarget() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 63c882d..9b5d8d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2220,7 +2220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api INPCModule module = World.RequestModuleInterface(); if (module != null) { - Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); + Vector3 pos = new Vector3((float)position.x, (float)position.y, (float)position.z); module.MoveToTarget(new UUID(npc.m_string), World, pos, noFly != 0); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 3f90788..9ed894c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -591,6 +591,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int STATS_ACTIVE_SCRIPTS = 19; public const int STATS_SCRIPT_LPS = 20; + // Constants for osNpc* functions + public const int OS_NPC_FLY = 0; + public const int OS_NPC_NO_FLY = 1; + public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; -- cgit v1.1 From 7f499ff3f386d57bcd81ebb3f58f110011100604 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 10 Aug 2011 23:56:19 +0100 Subject: Add a OS_NPC_LAND_AT_TARGET option to osMoveToTarget() Default for this function is now not to automatically land. This allows better control by scripts when an avatar is going to be landing on a prim rather than the ground. Stopping the avatar involves faking a collision, to avoid the pid controller making it overshoot. A better approach would be to gradually slow the avatar as we near the target --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 5 +++- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 5 ++++ .../Region/OptionalModules/World/NPC/NPCModule.cs | 33 ++++++++++++++-------- .../World/NPC/Tests/NPCModuleTests.cs | 4 +-- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 2 ++ .../Shared/Api/Implementation/OSSL_Api.cs | 11 ++++++-- .../Shared/Api/Runtime/LSL_Constants.cs | 1 + 7 files changed, 44 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 06296c9..08b973d 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -71,8 +71,11 @@ namespace OpenSim.Region.Framework.Interfaces /// If true, then the avatar will attempt to walk to the location even if it's up in the air. /// This is to allow walking on prims. /// + /// + /// If true and the avatar is flying when it reaches the target, land. + /// /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC - bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly); + bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget); /// /// Stop the NPC's current movement. diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index cfd692d..d63c2a6 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -37,6 +37,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC { public class NPCAvatar : IClientAPI { + /// + /// Signal whether the avatar should land when it reaches a move target + /// + public bool LandAtTarget { get; set; } + private readonly string m_firstname; private readonly string m_lastname; private readonly Vector3 m_startPos; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index d0b5a94..f38af46 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -75,19 +75,25 @@ namespace OpenSim.Region.OptionalModules.World.NPC // We are close enough to the target m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name); + presence.Velocity = Vector3.Zero; + presence.AbsolutePosition = presence.MoveToPositionTarget; + presence.ResetMoveToTarget(); + if (presence.PhysicsActor.Flying) { - Vector3 targetPos = presence.MoveToPositionTarget; - float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; - if (targetPos.Z - terrainHeight < 0.2) - { + for (int i = 0; i < 5; i++) + presence.PhysicsActor.IsColliding = true; + +// Vector3 targetPos = presence.MoveToPositionTarget; + if (m_avatars[presence.UUID].LandAtTarget) presence.PhysicsActor.Flying = false; - } - } - presence.Velocity = Vector3.Zero; - presence.AbsolutePosition = presence.MoveToPositionTarget; - presence.ResetMoveToTarget(); +// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; +// if (targetPos.Z - terrainHeight < 0.2) +// { +// presence.PhysicsActor.Flying = false; +// } + } // FIXME: This doesn't work if (presence.PhysicsActor.Flying) @@ -217,7 +223,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC return npcAvatar.AgentId; } - public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly) + public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget) { lock (m_avatars) { @@ -227,8 +233,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC scene.TryGetScenePresence(agentID, out sp); m_log.DebugFormat( - "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); + "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", + sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget); + m_avatars[agentID].LandAtTarget = landAtTarget; sp.MoveToTarget(pos, noFly); return true; @@ -263,6 +271,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC { if (m_avatars.ContainsKey(agentID)) { + ScenePresence sp; + scene.TryGetScenePresence(agentID, out sp); + m_avatars[agentID].Say(text); return true; diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 81497d5..d220fab 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); Vector3 targetPos = startPos + new Vector3(0, 0, 10); - npcModule.MoveToTarget(npc.UUID, scene, targetPos, false); + npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); @@ -135,7 +135,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // Try a second movement startPos = npc.AbsolutePosition; targetPos = startPos + new Vector3(10, 0, 0); - npcModule.MoveToTarget(npc.UUID, scene, targetPos, false); + npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); scene.Update(); diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 4f461ad..ecf5983 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -305,10 +305,12 @@ namespace OpenSim.Region.Physics.OdePlugin { m_iscolliding = true; } + if (m_wascolliding != m_iscolliding) { //base.SendCollisionUpdate(new CollisionEventUpdate()); } + m_wascolliding = m_iscolliding; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9b5d8d9..f83304b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2209,11 +2209,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (module != null) { Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); - module.MoveToTarget(new UUID(npc.m_string), World, pos, false); + module.MoveToTarget(new UUID(npc.m_string), World, pos, false, true); } } - public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector position, int noFly) + public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector position, int moveParams) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); @@ -2221,7 +2221,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (module != null) { Vector3 pos = new Vector3((float)position.x, (float)position.y, (float)position.z); - module.MoveToTarget(new UUID(npc.m_string), World, pos, noFly != 0); + module.MoveToTarget( + new UUID(npc.m_string), + World, + pos, + (moveParams & ScriptBaseClass.OS_NPC_NO_FLY) != 0, + (moveParams & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 9ed894c..e82c281 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -594,6 +594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase // Constants for osNpc* functions public const int OS_NPC_FLY = 0; public const int OS_NPC_NO_FLY = 1; + public const int OS_NPC_LAND_AT_TARGET = 2; public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; -- cgit v1.1 From 951ffad81e15a35bc9f847ea1448dd247a2e6e6f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 00:23:54 +0100 Subject: If SP.MoveToTarget has been called with a force walk, begin by landing the avatar. There is a bug here - once an avatar has landed it glides to its new position instead of performing a walk animation --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 +++- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b8e4e93..12a4712 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1723,7 +1723,9 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); - if (!noFly && pos.Z > terrainHeight) + if (noFly) + PhysicsActor.Flying = false; + else if (pos.Z > terrainHeight) PhysicsActor.Flying = true; MovingToTarget = true; diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index ecf5983..0a0d13f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -258,7 +258,11 @@ namespace OpenSim.Region.Physics.OdePlugin public override bool Flying { get { return flying; } - set { flying = value; } + set + { + flying = value; +// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); + } } /// -- cgit v1.1 From 4402851b086e7faf0d441d2ae0d5f6a3e1ea04b8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 01:56:42 +0100 Subject: Get NPCs to revert to the correct 'resting' animation (e.g. stand or hover) after finishing their movement. This also fixes judder after an avatar has finished "go here"/autopilot movement in a viewer. This meant reseting the SP.AgentControlFlags since the Animator uses these to determine the correct default animation. --- .../Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs | 10 ++++++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++++++ OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 8 +++----- .../Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 1 + .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 4ab818f..e07d8b4 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -77,6 +77,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_scenePresence.IsChildAgent) return; +// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name); + if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) SendAnimPack(); } @@ -91,6 +93,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (animID == UUID.Zero) return; +// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name); + AddAnimation(animID, objectID); } @@ -127,13 +131,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public void TrySetMovementAnimation(string anim) { - //m_log.DebugFormat("Updating movement animation to {0}", anim); - if (!m_scenePresence.IsChildAgent) { if (m_animations.TrySetDefaultAnimation( anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) { +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}", +// anim, m_scenePresence.Name); + // 16384 is CHANGED_ANIMATION m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); SendAnimPack(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 12a4712..7a30684 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1745,6 +1745,12 @@ namespace OpenSim.Region.Framework.Scenes MovingToTarget = false; MoveToPositionTarget = Vector3.Zero; + + // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct + // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. + // However, the line is here rather than in the NPC module since it also appears necessary to stop a + // viewer that uses "go here" from juddering on all subsequent avatar movements. + AgentControlFlags = (uint)AgentManager.ControlFlags.NONE; } private void CheckAtSitTarget() diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index f38af46..0e313df 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -95,11 +95,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC // } } - // FIXME: This doesn't work - if (presence.PhysicsActor.Flying) - presence.Animator.TrySetMovementAnimation("HOVER"); - else - presence.Animator.TrySetMovementAnimation("STAND"); +// m_log.DebugFormat( +// "[NPC MODULE]: AgentControlFlags {0}, MovementFlag {1} for {2}", +// presence.AgentControlFlags, presence.MovementFlag, presence.Name); } else { diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index d220fab..2742b67 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -131,6 +131,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos)); + Assert.That(npc.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE)); // Try a second movement startPos = npc.AbsolutePosition; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index f83304b..71fc15f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -870,7 +870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence target = (ScenePresence)World.Entities[avatarID]; if (target != null) { - UUID animID=UUID.Zero; + UUID animID = UUID.Zero; lock (m_host.TaskInventory) { foreach (KeyValuePair inv in m_host.TaskInventory) -- cgit v1.1 From cace6eaa8a82018fbb21ab83ce1bf95ea0a1e154 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 02:06:32 +0100 Subject: comment out some of the currently less useful debug log messages --- OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | 4 ++-- OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | 4 ++-- .../CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | 3 ++- .../CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 8db4e67..ff889ea 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -232,7 +232,7 @@ namespace OpenSim.Region.ClientStack.Linden public string SeedCapRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); +// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index e0807ee..22c05c4 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -118,7 +118,7 @@ namespace OpenSim.Region.ClientStack.Linden //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); if (m_URL == "localhost") { - m_log.InfoFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), delegate(Hashtable m_dhttpMethod) @@ -130,7 +130,7 @@ namespace OpenSim.Region.ClientStack.Linden } else { - m_log.InfoFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); caps.RegisterHandler("GetMesh", m_URL); } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 35eedb4..24ab06a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -128,12 +128,12 @@ namespace OpenSim.Region.ClientStack.Linden //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); if (m_URL == "localhost") { - m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); } else { - m_log.InfoFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); caps.RegisterHandler("GetTexture", m_URL); } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 6543845..d6063ad 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs @@ -93,7 +93,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser lookat = ((ScenePresence)sp).Lookat; } } - m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); + +// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index fa5b873..59a407f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence } } - m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); +// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); m_PresenceService.LogoutAgent(client.SessionId); } -- cgit v1.1 From ee22569c9262277467df9a4b15674a1472fa0b71 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 02:19:13 +0100 Subject: only accept npc UUIDs to osNpc* functions, not names (except for create) --- .../Shared/Api/Implementation/OSSL_Api.cs | 26 +++++++++------------- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 6 ++--- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 12 +++++----- 3 files changed, 20 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 71fc15f..91ac3b7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2153,7 +2153,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// The name of the notecard to which to save the appearance. /// The asset ID of the notecard saved. - public LSL_Key osNpcSaveAppearance(string avatar, string notecardName) + public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecardName) { CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); @@ -2161,20 +2161,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (npcModule != null) { - UUID avatarId = UUID.Zero; - if (!UUID.TryParse(avatar, out avatarId)) - return new LSL_Key(UUID.Zero.ToString()); + UUID npcId = new UUID(npc.m_string); - if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) + if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) return new LSL_Key(UUID.Zero.ToString()); - return SaveAppearanceToNotecard(avatarId, notecardName); + return SaveAppearanceToNotecard(npcId, notecardName); } return new LSL_Key(UUID.Zero.ToString()); } - public void osNpcLoadAppearance(string avatar, string notecardNameOrUuid) + public void osNpcLoadAppearance(LSL_Key npc, string notecardNameOrUuid) { CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); @@ -2182,11 +2180,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (npcModule != null) { - UUID avatarId = UUID.Zero; - if (!UUID.TryParse(avatar, out avatarId)) - return; + UUID npcId = new UUID(npc.m_string); - if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) + if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) return; string appearanceSerialized = LoadNotecard(notecardNameOrUuid); @@ -2197,7 +2193,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api AvatarAppearance appearance = new AvatarAppearance(); appearance.Unpack(appearanceOsd); - npcModule.SetNPCAppearance(avatarId, appearance, m_host.ParentGroup.Scene); + npcModule.SetNPCAppearance(npcId, appearance, m_host.ParentGroup.Scene); } } @@ -2213,7 +2209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector position, int moveParams) + public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector position, int options) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); @@ -2225,8 +2221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api new UUID(npc.m_string), World, pos, - (moveParams & ScriptBaseClass.OS_NPC_NO_FLY) != 0, - (moveParams & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0); + (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, + (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 56be9d9..f4a618b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -170,10 +170,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces key osNpcCreate(string user, string name, vector position, key cloneFrom); - LSL_Key osNpcSaveAppearance(string avatar, string notecardName); - void osNpcLoadAppearance(string avatar, string notecardNameOrUuid); + LSL_Key osNpcSaveAppearance(key npc, string notecardName); + void osNpcLoadAppearance(key npc, string notecardNameOrUuid); void osNpcMoveTo(key npc, vector position); - void osNpcMoveToTarget(key npc, vector position, int noFly); + void osNpcMoveToTarget(key npc, vector position, int options); void osNpcStopMoveTo(LSL_Key npc); void osNpcSay(key npc, string message); void osNpcRemove(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index c745e5c..84d61f4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -483,14 +483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); } - public key osNpcSaveAppearance(string avatar, string notecardName) + public key osNpcSaveAppearance(key npc, string notecardName) { - return m_OSSL_Functions.osNpcSaveAppearance(avatar, notecardName); + return m_OSSL_Functions.osNpcSaveAppearance(npc, notecardName); } - public void osNpcLoadAppearance(string avatar, string notecardNameOrUuid) + public void osNpcLoadAppearance(key npc, string notecardNameOrUuid) { - m_OSSL_Functions.osNpcLoadAppearance(avatar, notecardNameOrUuid); + m_OSSL_Functions.osNpcLoadAppearance(npc, notecardNameOrUuid); } public void osNpcMoveTo(key npc, vector position) @@ -498,9 +498,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcMoveTo(npc, position); } - public void osNpcMoveToTarget(key npc, vector position, int noFly) + public void osNpcMoveToTarget(key npc, vector position, int options) { - m_OSSL_Functions.osNpcMoveToTarget(npc, position, noFly); + m_OSSL_Functions.osNpcMoveToTarget(npc, position, options); } public void osNpcStopMoveTo(LSL_Key npc) -- cgit v1.1 From 29093df1a7f3d2816d1b446524b2de18b0b5ac45 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 02:36:02 +0100 Subject: get rid of intermediate local store of body rotation in ScenePresence, this is not used. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7a30684..e28d1fe 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -173,7 +173,7 @@ namespace OpenSim.Region.Framework.Scenes private float m_speedModifier = 1.0f; - private Quaternion m_bodyRot= Quaternion.Identity; + private Quaternion m_bodyRot = Quaternion.Identity; private Quaternion m_bodyRotPrevious = Quaternion.Identity; @@ -1397,7 +1397,6 @@ namespace OpenSim.Region.Framework.Scenes bool update_rotation = false; bool DCFlagKeyPressed = false; Vector3 agent_control_v3 = Vector3.Zero; - Quaternion q = bodyRotation; bool oldflying = PhysicsActor.Flying; @@ -1411,9 +1410,9 @@ namespace OpenSim.Region.Framework.Scenes if (actor.Flying != oldflying) update_movementflag = true; - if (q != m_bodyRot) + if (bodyRotation != m_bodyRot) { - m_bodyRot = q; + m_bodyRot = bodyRotation; update_rotation = true; } @@ -1535,7 +1534,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); - AddNewMovement(agent_control_v3, q); + AddNewMovement(agent_control_v3, bodyRotation); } if (update_movementflag -- cgit v1.1 From 36f7d36fa1556d2b9356bc9bc5d9b16fc81eb96a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 02:54:15 +0100 Subject: instead of setting avatar rotation twice in SP.HandleAgentUpdate(), eliminate the second setting in AddNewMovement() --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 30 ++++++++++------------ .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e28d1fe..a1bd672 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1298,7 +1298,6 @@ namespace OpenSim.Region.Framework.Scenes #region Inputs AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; - Quaternion bodyRotation = agentData.BodyRotation; // Camera location in world. We'll need to raytrace // from this location from time to time. @@ -1384,6 +1383,15 @@ namespace OpenSim.Region.Framework.Scenes if (m_allowMovement && !SitGround) { + Quaternion bodyRotation = agentData.BodyRotation; + bool update_rotation = false; + + if (bodyRotation != m_bodyRot) + { + Rotation = bodyRotation; + update_rotation = true; + } + bool update_movementflag = false; if (agentData.UseClientAgentPosition) @@ -1393,8 +1401,6 @@ namespace OpenSim.Region.Framework.Scenes } int i = 0; - - bool update_rotation = false; bool DCFlagKeyPressed = false; Vector3 agent_control_v3 = Vector3.Zero; @@ -1410,12 +1416,6 @@ namespace OpenSim.Region.Framework.Scenes if (actor.Flying != oldflying) update_movementflag = true; - if (bodyRotation != m_bodyRot) - { - m_bodyRot = bodyRotation; - update_rotation = true; - } - if (m_parentID == 0) { bool bAllowUpdateMoveToPosition = false; @@ -1467,8 +1467,8 @@ namespace OpenSim.Region.Framework.Scenes ) // This or is for Nudge forward { m_movementflag -= ((byte)(uint)DCF); - update_movementflag = true; + /* if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) && ((m_movementflag & (byte)nudgehack) == nudgehack)) @@ -1534,7 +1534,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); - AddNewMovement(agent_control_v3, bodyRotation); + AddNewMovement(agent_control_v3); } if (update_movementflag @@ -1732,7 +1732,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 agent_control_v3 = new Vector3(); HandleMoveToTargetUpdate(ref agent_control_v3, Rotation); - AddNewMovement(agent_control_v3, Rotation); + AddNewMovement(agent_control_v3); } /// @@ -2311,13 +2311,11 @@ namespace OpenSim.Region.Framework.Scenes /// Rotate the avatar to the given rotation and apply a movement in the given relative vector /// /// The vector in which to move. This is relative to the rotation argument - /// The direction in which this avatar should now face. - public void AddNewMovement(Vector3 vec, Quaternion rotation) + public void AddNewMovement(Vector3 vec) { m_perfMonMS = Util.EnvironmentTickCount(); - Rotation = rotation; - Vector3 direc = vec * rotation; + Vector3 direc = vec * Rotation; direc.Normalize(); direc *= 0.03f * 128f * m_speedModifier; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 0e313df..9b86abb 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -107,7 +107,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC Vector3 agent_control_v3 = new Vector3(); presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation); - presence.AddNewMovement(agent_control_v3, presence.Rotation); + presence.AddNewMovement(agent_control_v3); } // //// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null); -- cgit v1.1 From 1aa171189397f34d7d18fb358f7bd767d241675a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 03:05:51 +0100 Subject: eliminate the rotation parameter from SP.HandleMoveToTargetUpdate(). This can just use the currently set Rotation looks like I spoke to soon about eliminating jerkiness on "go here"/autopilot. It's still there. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++++----- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 7 ++++++- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a1bd672..afa896c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1496,7 +1496,7 @@ namespace OpenSim.Region.Framework.Scenes } else if (bAllowUpdateMoveToPosition) { - if (HandleMoveToTargetUpdate(ref agent_control_v3, bodyRotation)) + if (HandleMoveToTargetUpdate(ref agent_control_v3)) update_movementflag = true; } } @@ -1556,9 +1556,8 @@ namespace OpenSim.Region.Framework.Scenes /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3. /// /// Cumulative agent movement that this method will update. - /// New body rotation of the avatar. /// True if movement has been updated in some way. False otherwise. - public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3, Quaternion bodyRotation) + public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) { // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); @@ -1594,7 +1593,7 @@ namespace OpenSim.Region.Framework.Scenes // to such forces, but the following simple approach seems to works fine. Vector3 LocalVectorToTarget3D = (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords + * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords // Ignore z component of vector // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); LocalVectorToTarget3D.Normalize(); @@ -1731,7 +1730,7 @@ namespace OpenSim.Region.Framework.Scenes MoveToPositionTarget = pos; Vector3 agent_control_v3 = new Vector3(); - HandleMoveToTargetUpdate(ref agent_control_v3, Rotation); + HandleMoveToTargetUpdate(ref agent_control_v3); AddNewMovement(agent_control_v3); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 9b86abb..580d7ef 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -81,6 +81,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC if (presence.PhysicsActor.Flying) { + // A horrible hack to stop the NPC dead in its tracks rather than having them overshoot + // the target if flying. + // We really need to be more subtle (slow the avatar as it approaches the target) or at + // least be able to set collision status once, rather than 5 times to give it enough + // weighting so that that PhysicsActor thinks it really is colliding. for (int i = 0; i < 5; i++) presence.PhysicsActor.IsColliding = true; @@ -106,7 +111,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); Vector3 agent_control_v3 = new Vector3(); - presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation); + presence.HandleMoveToTargetUpdate(ref agent_control_v3); presence.AddNewMovement(agent_control_v3); } // -- cgit v1.1 From 3d4cc93a8e46847d4852eb3fd038ec48c284c18e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 03:07:41 +0100 Subject: minor: a little bit of log message correction/commenting out --- OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs index aa14054..1d2141e 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs @@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap private Bitmap fetchTexture(UUID id) { AssetBase asset = m_scene.AssetService.Get(id.ToString()); - m_log.DebugFormat("Fetched texture {0}, found: {1}", id, asset != null); + m_log.DebugFormat("[TexturedMapTileRenderer]: Fetched texture {0}, found: {1}", id, asset != null); if (asset == null) return null; ManagedImage managedImage; -- cgit v1.1 From b3a4b1053157d65d0068bf5b3362dc28da4be85a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 03:16:46 +0100 Subject: eliminate redundant ground sitting checks since these are already done in enclosing control structures --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index afa896c..18632d7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1537,10 +1537,7 @@ namespace OpenSim.Region.Framework.Scenes AddNewMovement(agent_control_v3); } - if (update_movementflag - && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) - && (m_parentID == 0) - && !SitGround) + if (update_movementflag && m_parentID == 0) Animator.UpdateMovementAnimations(); } -- cgit v1.1 From 83ca5a101d5578282ba0fd7177fcb618f70d3cc9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 20:56:18 +0100 Subject: Split out to-be-common setup stuff from TestOsOwnerSaveAppearance() --- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 48 +++++++++++++++------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index fc8b551..2218a1f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -50,35 +50,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests [TestFixture] public class OSSL_ApiAppearanceTest { - [Test] - public void TestOsOwnerSaveAppearance() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); + protected Scene m_scene; + protected XEngine.XEngine m_engine; + [SetUp] + public void SetUp() + { IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); config.Set("AllowOSFunctions", "true"); config.Set("OSFunctionThreatLevel", "Severe"); + m_scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, new AvatarFactoryModule()); + + m_engine = new XEngine.XEngine(); + m_engine.Initialise(initConfigSource); + m_engine.AddRegion(m_scene); + } + + /// + /// Test creation of an NPC where the appearance data comes from a notecard + /// +// [Test] +// public void TestOsNpcCreateFromNotecard() +// { +// TestHelpers.InMethod(); +//// log4net.Config.XmlConfigurator.Configure(); +// } + + [Test] + public void TestOsOwnerSaveAppearance() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + UUID userId = TestHelpers.ParseTail(0x1); float newHeight = 1.9f; - Scene scene = SceneHelpers.SetupScene(); - SceneHelpers.SetupSceneModules(scene, new AvatarFactoryModule()); - ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); sp.Appearance.AvatarHeight = newHeight; SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); SceneObjectPart part = so.RootPart; - scene.AddSceneObject(so); - - XEngine.XEngine engine = new XEngine.XEngine(); - engine.Initialise(initConfigSource); - engine.AddRegion(scene); + m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); string notecardName = "appearanceNc"; @@ -90,7 +108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests TaskInventoryItem ncItem = items[0]; Assert.That(ncItem.Name, Is.EqualTo(notecardName)); - AssetBase ncAsset = scene.AssetService.Get(ncItem.AssetID.ToString()); + AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString()); Assert.That(ncAsset, Is.Not.Null); AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data); -- cgit v1.1 From 50945dd56029a1280c581ea9b29213ab0e162a0a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 21:43:26 +0100 Subject: add regression test for osNpcCreate when cloning an in-region avatar --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 4 +- .../Region/OptionalModules/World/NPC/NPCModule.cs | 29 +------- .../World/NPC/Tests/NPCModuleTests.cs | 10 +-- .../Shared/Api/Implementation/OSSL_Api.cs | 6 +- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 79 ++++++++++++++++++++-- 5 files changed, 87 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 08b973d..5e5c4a1 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -40,9 +40,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// - /// The UUID of the avatar from which to clone the NPC's appearance from. + /// The avatar appearance to use for the new NPC. /// The UUID of the ScenePresence created. - UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); + UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance); /// /// Check if the agent is an NPC. diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 580d7ef..c764c20 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -45,7 +45,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Dictionary m_avatars = new Dictionary(); - private Dictionary m_appearanceCache = new Dictionary(); public void Initialise(Scene scene, IConfigSource source) { @@ -124,28 +123,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC } } - private AvatarAppearance GetAppearance(UUID target, Scene scene) - { - if (m_appearanceCache.ContainsKey(target)) - return m_appearanceCache[target]; - - ScenePresence originalPresence = scene.GetScenePresence(target); - - if (originalPresence != null) - { - AvatarAppearance originalAppearance = originalPresence.Appearance; - m_appearanceCache.Add(target, originalAppearance); - return originalAppearance; - } - else - { - m_log.DebugFormat( - "[NPC MODULE]: Avatar {0} is not in the scene for us to grab baked textures from them. Using defaults.", target); - - return new AvatarAppearance(); - } - } - public bool IsNPC(UUID agentId, Scene scene) { ScenePresence sp = scene.GetScenePresence(agentId); @@ -176,7 +153,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC return true; } - public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) + public UUID CreateNPC( + string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance) { NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue); @@ -191,8 +169,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC acd.lastname = lastname; acd.ServiceURLs = new Dictionary(); - AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene); - AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true); + AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); acd.Appearance = npcAppearance; // for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++) diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 2742b67..f8afc5a 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); - IClientAPI originalClient = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)).ControllingClient; + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance @@ -72,10 +72,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); - afm.SetAppearanceFromClient(originalClient, originalTe, null); + afm.SetAppearanceFromClient(sp.ControllingClient, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface(); - UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); + UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); ScenePresence npc = scene.GetScenePresence(npcId); @@ -96,12 +96,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, config, new NPCModule()); - IClientAPI originalClient = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)).ControllingClient; + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); Vector3 startPos = new Vector3(128, 128, 30); INPCModule npcModule = scene.RequestModuleInterface(); - UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, originalClient.AgentId); + UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance); ScenePresence npc = scene.GetScenePresence(npcId); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 91ac3b7..b18aa3b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2135,11 +2135,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api INPCModule module = World.RequestModuleInterface(); if (module != null) { + ScenePresence clonePresence = World.GetScenePresence(new UUID(cloneFrom.m_string)); + if (clonePresence == null) + return new LSL_Key(UUID.Zero.ToString()); + UUID x = module.CreateNPC(firstname, lastname, new Vector3((float) position.x, (float) position.y, (float) position.z), World, - new UUID(cloneFrom)); + clonePresence.Appearance); return new LSL_Key(x.ToString()); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 2218a1f..7f778d7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -27,7 +27,9 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; +using log4net; using Nini.Config; using NUnit.Framework; using OpenMetaverse; @@ -35,6 +37,7 @@ using OpenMetaverse.Assets; using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.CoreModules.Avatar.AvatarFactory; +using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; @@ -61,9 +64,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests config.Set("Enabled", "true"); config.Set("AllowOSFunctions", "true"); config.Set("OSFunctionThreatLevel", "Severe"); + config = initConfigSource.AddConfig("NPC"); + config.Set("Enabled", "true"); m_scene = SceneHelpers.SetupScene(); - SceneHelpers.SetupSceneModules(m_scene, new AvatarFactoryModule()); + SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule()); m_engine = new XEngine.XEngine(); m_engine.Initialise(initConfigSource); @@ -73,12 +78,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// /// Test creation of an NPC where the appearance data comes from a notecard /// -// [Test] -// public void TestOsNpcCreateFromNotecard() -// { -// TestHelpers.InMethod(); -//// log4net.Config.XmlConfigurator.Configure(); -// } + //[Test] + public void TestOsNpcCreateFromNotecard() + { + TestHelpers.InMethod(); + log4net.Config.XmlConfigurator.Configure(); + + // Store an avatar with a different height from default in a notecard. + UUID userId = TestHelpers.ParseTail(0x1); + float newHeight = 1.9f; + + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); + sp.Appearance.AvatarHeight = newHeight; + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectPart part = so.RootPart; + m_scene.AddSceneObject(so); + + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + + string notecardName = "appearanceNc"; + osslApi.osOwnerSaveAppearance(notecardName); + + // Try creating a bot using the appearance in the notecard. + string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName); + Assert.That(npcRaw, Is.Not.Null); + + UUID npcId = new UUID(npcRaw); + ScenePresence npc = m_scene.GetScenePresence(npcId); + Assert.That(npc, Is.Not.Null); + Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight)); + } + + /// + /// Test creation of an NPC where the appearance data comes from an avatar already in the region. + /// + [Test] + public void TestOsNpcCreateFromAvatar() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // Store an avatar with a different height from default in a notecard. + UUID userId = TestHelpers.ParseTail(0x1); + float newHeight = 1.9f; + + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); + sp.Appearance.AvatarHeight = newHeight; + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectPart part = so.RootPart; + m_scene.AddSceneObject(so); + + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + + string notecardName = "appearanceNc"; + osslApi.osOwnerSaveAppearance(notecardName); + + // Try creating a bot using the existing avatar's appearance + string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString()); + Assert.That(npcRaw, Is.Not.Null); + + UUID npcId = new UUID(npcRaw); + ScenePresence npc = m_scene.GetScenePresence(npcId); + Assert.That(npc, Is.Not.Null); + Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight)); + } [Test] public void TestOsOwnerSaveAppearance() -- cgit v1.1 From b1ae930c6b8e7d985e2c148a4e18a59ac880dcbd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 22:26:47 +0100 Subject: Implement osAgentSaveAppearance() to save the appearance of an avatar in the region to a notecard This is separate from osOwnerSaveAppearance() so that owner saves can be allowed without allowing arbitrary avatar saves --- .../Shared/Api/Implementation/OSSL_Api.cs | 35 +++++++++++++++--- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 +- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++ .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 41 ++++++++++++++++++++++ 4 files changed, 78 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b18aa3b..939602a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2165,7 +2165,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (npcModule != null) { - UUID npcId = new UUID(npc.m_string); + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) + return new LSL_Key(UUID.Zero.ToString()); if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) return new LSL_Key(UUID.Zero.ToString()); @@ -2273,14 +2275,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return SaveAppearanceToNotecard(m_host.OwnerID, notecardName); } - protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecardName) + public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecardName) + { + CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance"); + + return SaveAppearanceToNotecard(avatarId, notecardName); + } + + protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecardName) { IAvatarFactory appearanceModule = World.RequestModuleInterface(); if (appearanceModule != null) { - appearanceModule.SaveBakedTextures(m_host.OwnerID); - ScenePresence sp = m_host.ParentGroup.Scene.GetScenePresence(m_host.OwnerID); + appearanceModule.SaveBakedTextures(sp.UUID); OSDMap appearancePacked = sp.Appearance.Pack(); TaskInventoryItem item @@ -2293,6 +2301,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Key(UUID.Zero.ToString()); } } + + protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecardName) + { + ScenePresence sp = World.GetScenePresence(avatarId); + + if (sp == null || sp.IsChildAgent) + return new LSL_Key(UUID.Zero.ToString()); + + return SaveAppearanceToNotecard(sp, notecardName); + } + + protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecardName) + { + UUID avatarId; + if (!UUID.TryParse(rawAvatarId, out avatarId)) + return new LSL_Key(UUID.Zero.ToString()); + + return SaveAppearanceToNotecard(avatarId, notecardName); + } /// /// Get current region's map texture UUID diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index f4a618b..88e1f15 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -168,7 +168,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); - key osNpcCreate(string user, string name, vector position, key cloneFrom); LSL_Key osNpcSaveAppearance(key npc, string notecardName); void osNpcLoadAppearance(key npc, string notecardNameOrUuid); @@ -179,6 +178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcRemove(key npc); LSL_Key osOwnerSaveAppearance(string notecardName); + LSL_Key osAgentSaveAppearance(key agentId, string notecardName); key osGetMapTexture(); key osGetRegionMapTexture(string regionName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 84d61f4..4701736 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -523,6 +523,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osOwnerSaveAppearance(notecardName); } + public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecardName) + { + return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecardName); + } + public OSSLPrim Prim; [Serializable] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 7f778d7..85cf507 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -184,5 +184,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight)); } + + [Test] + public void TestOsAgentSaveAppearance() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID ownerId = TestHelpers.ParseTail(0x1); + UUID nonOwnerId = TestHelpers.ParseTail(0x2); + float newHeight = 1.9f; + + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId); + sp.Appearance.AvatarHeight = newHeight; + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId); + SceneObjectPart part = so.RootPart; + m_scene.AddSceneObject(so); + + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + + string notecardName = "appearanceNc"; + + osslApi.osAgentSaveAppearance(new LSL_Types.LSLString(nonOwnerId.ToString()), notecardName); + + IList items = part.Inventory.GetInventoryItems(notecardName); + Assert.That(items.Count, Is.EqualTo(1)); + + TaskInventoryItem ncItem = items[0]; + Assert.That(ncItem.Name, Is.EqualTo(notecardName)); + + AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString()); + Assert.That(ncAsset, Is.Not.Null); + + AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data); + anc.Decode(); + OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText); + AvatarAppearance savedAppearance = new AvatarAppearance(); + savedAppearance.Unpack(appearanceOsd); + + Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight)); + } } } \ No newline at end of file -- cgit v1.1 From a21e98ae1a3e2f570cc119e020d4d4ea111e0ad2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 23:28:14 +0100 Subject: implement osNpcGetRot() and osNpcSetRot() Rotation works if done around the z axis. Anything else leads to random results. --- .../Shared/Api/Implementation/LSL_Api.cs | 3 +- .../Shared/Api/Implementation/OSSL_Api.cs | 57 ++++++++++++++++++++-- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 10 ++++ 4 files changed, 67 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 86ee28a..8a281d4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -369,7 +369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // convert a LSL_Rotation to a Quaternion - protected Quaternion Rot2Quaternion(LSL_Rotation r) + public static Quaternion Rot2Quaternion(LSL_Rotation r) { Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); q.Normalize(); @@ -2061,6 +2061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { return llGetRootRotation(); } + m_host.AddScriptLPS(1); Quaternion q = m_host.GetWorldRotation(); return new LSL_Rotation(q.X, q.Y, q.Z, q.W); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 939602a..1874826 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2186,9 +2186,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (npcModule != null) { - UUID npcId = new UUID(npc.m_string); - - if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) return; string appearanceSerialized = LoadNotecard(notecardNameOrUuid); @@ -2210,8 +2209,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api INPCModule module = World.RequestModuleInterface(); if (module != null) { + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) + return; + Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); - module.MoveToTarget(new UUID(npc.m_string), World, pos, false, true); + module.MoveToTarget(npcId, World, pos, false, true); } } @@ -2222,6 +2225,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api INPCModule module = World.RequestModuleInterface(); if (module != null) { + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) + return; + Vector3 pos = new Vector3((float)position.x, (float)position.y, (float)position.z); module.MoveToTarget( new UUID(npc.m_string), @@ -2232,6 +2239,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public LSL_Rotation osNpcGetRot(LSL_Key npc) + { + CheckThreatLevel(ThreatLevel.High, "osNpcGetRot"); + + INPCModule npcModule = World.RequestModuleInterface(); + if (npcModule != null) + { + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) + return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); + + if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) + return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); + + ScenePresence sp = World.GetScenePresence(npcId); + Quaternion rot = sp.Rotation; + + return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); + } + + return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); + } + + public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) + { + CheckThreatLevel(ThreatLevel.High, "osNpcSetRot"); + + INPCModule npcModule = World.RequestModuleInterface(); + if (npcModule != null) + { + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) + return; + + if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) + return; + + ScenePresence sp = World.GetScenePresence(npcId); + sp.Rotation = LSL_Api.Rot2Quaternion(rotation); + } + } + public void osNpcStopMoveTo(LSL_Key npc) { CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 88e1f15..7c08e84 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -173,6 +173,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcLoadAppearance(key npc, string notecardNameOrUuid); void osNpcMoveTo(key npc, vector position); void osNpcMoveToTarget(key npc, vector position, int options); + rotation osNpcGetRot(key npc); + void osNpcSetRot(LSL_Key npc, rotation rot); void osNpcStopMoveTo(LSL_Key npc); void osNpcSay(key npc, string message); void osNpcRemove(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 4701736..e8e5f52 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -503,6 +503,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcMoveToTarget(npc, position, options); } + public rotation osNpcGetRot(key npc) + { + return m_OSSL_Functions.osNpcGetRot(npc); + } + + public void osNpcSetRot(key npc, rotation rot) + { + m_OSSL_Functions.osNpcSetRot(npc, rot); + } + public void osNpcStopMoveTo(LSL_Key npc) { m_OSSL_Functions.osNpcStopMoveTo(npc); -- cgit v1.1 From d23d37d2aa7c5a3d9c6ec1726aef7941d5e52519 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Aug 2011 23:36:22 +0100 Subject: implement osNpcGetPos() --- .../Shared/Api/Implementation/OSSL_Api.cs | 21 +++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++++ 3 files changed, 27 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 1874826..b1066b5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2202,6 +2202,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public LSL_Vector osNpcGetPos(LSL_Key npc) + { + CheckThreatLevel(ThreatLevel.High, "osNpcGetPos"); + + INPCModule npcModule = World.RequestModuleInterface(); + if (npcModule != null) + { + UUID npcId; + if (!UUID.TryParse(npc.m_string, out npcId)) + return new LSL_Vector(0, 0, 0); + + if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) + return new LSL_Vector(0, 0, 0); + + Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition; + return new LSL_Vector(pos.X, pos.Y, pos.Z); + } + + return new LSL_Vector(0, 0, 0); + } + public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 7c08e84..9f0d07c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -171,6 +171,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces key osNpcCreate(string user, string name, vector position, key cloneFrom); LSL_Key osNpcSaveAppearance(key npc, string notecardName); void osNpcLoadAppearance(key npc, string notecardNameOrUuid); + vector osNpcGetPos(key npc); void osNpcMoveTo(key npc, vector position); void osNpcMoveToTarget(key npc, vector position, int options); rotation osNpcGetRot(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index e8e5f52..3ccb3f1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -493,6 +493,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcLoadAppearance(npc, notecardNameOrUuid); } + public vector osNpcGetPos(LSL_Key npc) + { + return m_OSSL_Functions.osNpcGetPos(npc); + } + public void osNpcMoveTo(key npc, vector position) { m_OSSL_Functions.osNpcMoveTo(npc, position); -- cgit v1.1 From 0a1bbc27d26a430c53e84e22b7aad0df2f1f4a09 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 00:14:06 +0100 Subject: Allow the osNpcCreate() function to accept a notecard name or asset for initial appearance --- .../Shared/Api/Implementation/OSSL_Api.cs | 28 ++++++++++++++++++---- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 4 ++-- 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b1066b5..90c4636 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2130,20 +2130,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); - //QueueUserWorkItem INPCModule module = World.RequestModuleInterface(); if (module != null) { - ScenePresence clonePresence = World.GetScenePresence(new UUID(cloneFrom.m_string)); - if (clonePresence == null) + AvatarAppearance appearance = null; + + UUID cloneId; + if (UUID.TryParse(cloneFrom, out cloneId)) + { + ScenePresence clonePresence = World.GetScenePresence(new UUID(cloneFrom.m_string)); + if (clonePresence != null) + appearance = clonePresence.Appearance; + } + + if (appearance == null) + { + string appearanceSerialized = LoadNotecard(cloneFrom.m_string); + + if (appearanceSerialized != null) + { + OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); + appearance = new AvatarAppearance(); + appearance.Unpack(appearanceOsd); + } + } + + if (appearance == null) return new LSL_Key(UUID.Zero.ToString()); UUID x = module.CreateNPC(firstname, lastname, new Vector3((float) position.x, (float) position.y, (float) position.z), World, - clonePresence.Appearance); + appearance); return new LSL_Key(x.ToString()); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 85cf507..7573dff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -78,11 +78,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// /// Test creation of an NPC where the appearance data comes from a notecard /// - //[Test] + [Test] public void TestOsNpcCreateFromNotecard() { TestHelpers.InMethod(); - log4net.Config.XmlConfigurator.Configure(); +// log4net.Config.XmlConfigurator.Configure(); // Store an avatar with a different height from default in a notecard. UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From 65c4b8d37b304c4b6c09c0c4b07184c4a7ffda7d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 00:51:05 +0100 Subject: Fix kicking of NPCs via "kick user" console command. Needed to hook up the Close() function in the NPCAvatar IClientAPI implementation, which [unfortunately] is still needed --- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index d63c2a6..4441579 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -842,6 +842,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Close() { + // Remove ourselves from the scene + m_scene.RemoveClient(AgentId, false); } public void Start() -- cgit v1.1 From 2169cf04f92a6465fe9cd58a2bac0d1380a561bd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 01:24:15 +0100 Subject: When saving appearance, only save the baked textures, not the other face textures (which are already stored permanently) --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 48 +++++++++++++++++++--- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 75d8143..4627701 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -271,16 +271,30 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", sp.Name, m_scene.RegionInfo.RegionName); - for (int i = 0; i < faceTextures.Length; i++) + foreach (int i in Enum.GetValues(typeof(BakeType))) { + BakeType bakeType = (BakeType)i; + + if (bakeType == BakeType.Unknown) + continue; + // m_log.DebugFormat( // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); - if (faceTextures[i] == null) + int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); + Primitive.TextureEntryFace bakedTextureFace = faceTextures[ftIndex]; + + if (bakedTextureFace == null) + { + m_log.WarnFormat( + "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", + bakeType, sp.Name, m_scene.RegionInfo.RegionName); + continue; + } - AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString()); + AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString()); if (asset != null) { @@ -290,11 +304,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory else { m_log.WarnFormat( - "[AV FACTORY]: Baked texture {0} for {1} in {2} unexpectedly not found when trying to save permanently", - faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName); + "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently", + bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName); } } +// for (int i = 0; i < faceTextures.Length; i++) +// { +//// m_log.DebugFormat( +//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", +//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); +// +// if (faceTextures[i] == null) +// continue; +// +// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString()); +// +// if (asset != null) +// { +// asset.Temporary = false; +// m_scene.AssetService.Store(asset); +// } +// else +// { +// m_log.WarnFormat( +// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently", +// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName); +// } +// } + return true; } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 4441579..31e79fa 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -843,7 +843,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Close() { // Remove ourselves from the scene - m_scene.RemoveClient(AgentId, false); + m_scene.RemoveClient(AgentId, false); } public void Start() -- cgit v1.1 From aebd46a4348cf55d25eaa56325940a0f33d8b8fe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 01:32:49 +0100 Subject: rename osNpcStopMoveTo() to osNpcStopMoveToTarget() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 90c4636..07473e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2322,7 +2322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public void osNpcStopMoveTo(LSL_Key npc) + public void osNpcStopMoveToTarget(LSL_Key npc) { CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 9f0d07c..2ba68ff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -176,7 +176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcMoveToTarget(key npc, vector position, int options); rotation osNpcGetRot(key npc); void osNpcSetRot(LSL_Key npc, rotation rot); - void osNpcStopMoveTo(LSL_Key npc); + void osNpcStopMoveToTarget(LSL_Key npc); void osNpcSay(key npc, string message); void osNpcRemove(key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 3ccb3f1..140501c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -518,9 +518,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcSetRot(npc, rot); } - public void osNpcStopMoveTo(LSL_Key npc) + public void osNpcStopMoveToTarget(LSL_Key npc) { - m_OSSL_Functions.osNpcStopMoveTo(npc); + m_OSSL_Functions.osNpcStopMoveToTarget(npc); } public void osNpcSay(key npc, string message) -- cgit v1.1 From 16ac5413ddb57ac347addebc82d425364a083637 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 01:52:12 +0100 Subject: rename position parameter in osNpcMoveToTarget to target --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 4 ++-- OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 07473e5..2e28907 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2259,7 +2259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector position, int options) + public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); @@ -2270,7 +2270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(npc.m_string, out npcId)) return; - Vector3 pos = new Vector3((float)position.x, (float)position.y, (float)position.z); + Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z); module.MoveToTarget( new UUID(npc.m_string), World, diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 2ba68ff..1f3454f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -173,7 +173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcLoadAppearance(key npc, string notecardNameOrUuid); vector osNpcGetPos(key npc); void osNpcMoveTo(key npc, vector position); - void osNpcMoveToTarget(key npc, vector position, int options); + void osNpcMoveToTarget(key npc, vector target, int options); rotation osNpcGetRot(key npc); void osNpcSetRot(LSL_Key npc, rotation rot); void osNpcStopMoveToTarget(LSL_Key npc); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 140501c..13cf7fa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -503,9 +503,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcMoveTo(npc, position); } - public void osNpcMoveToTarget(key npc, vector position, int options) + public void osNpcMoveToTarget(key npc, vector target, int options) { - m_OSSL_Functions.osNpcMoveToTarget(npc, position, options); + m_OSSL_Functions.osNpcMoveToTarget(npc, target, options); } public rotation osNpcGetRot(key npc) -- cgit v1.1 From 76e0afe83f012e451a66a145c50e79c1bd047f37 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 02:46:44 +0100 Subject: tidy up some OSSL NPC parameter names --- .../Shared/Api/Implementation/OSSL_Api.cs | 42 +++++++++++----------- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 10 +++--- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 16 ++++----- 3 files changed, 34 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 2e28907..d791885 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2127,7 +2127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return retVal; } - public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) + public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); @@ -2136,17 +2136,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { AvatarAppearance appearance = null; - UUID cloneId; - if (UUID.TryParse(cloneFrom, out cloneId)) + UUID id; + if (UUID.TryParse(notecard, out id)) { - ScenePresence clonePresence = World.GetScenePresence(new UUID(cloneFrom.m_string)); + ScenePresence clonePresence = World.GetScenePresence(id); if (clonePresence != null) appearance = clonePresence.Appearance; } if (appearance == null) { - string appearanceSerialized = LoadNotecard(cloneFrom.m_string); + string appearanceSerialized = LoadNotecard(notecard); if (appearanceSerialized != null) { @@ -2175,9 +2175,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Save the current appearance of the NPC permanently to the named notecard. /// /// - /// The name of the notecard to which to save the appearance. + /// The name of the notecard to which to save the appearance. /// The asset ID of the notecard saved. - public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecardName) + public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard) { CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); @@ -2192,13 +2192,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) return new LSL_Key(UUID.Zero.ToString()); - return SaveAppearanceToNotecard(npcId, notecardName); + return SaveAppearanceToNotecard(npcId, notecard); } return new LSL_Key(UUID.Zero.ToString()); } - public void osNpcLoadAppearance(LSL_Key npc, string notecardNameOrUuid) + public void osNpcLoadAppearance(LSL_Key npc, string notecard) { CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); @@ -2210,7 +2210,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(npc.m_string, out npcId)) return; - string appearanceSerialized = LoadNotecard(notecardNameOrUuid); + string appearanceSerialized = LoadNotecard(notecard); OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); // OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized); // Console.WriteLine("appearanceSerialized {0}", appearanceSerialized); @@ -2356,23 +2356,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// Save the current appearance of the script owner permanently to the named notecard. /// - /// The name of the notecard to which to save the appearance. + /// The name of the notecard to which to save the appearance. /// The asset ID of the notecard saved. - public LSL_Key osOwnerSaveAppearance(string notecardName) + public LSL_Key osOwnerSaveAppearance(string notecard) { CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance"); - return SaveAppearanceToNotecard(m_host.OwnerID, notecardName); + return SaveAppearanceToNotecard(m_host.OwnerID, notecard); } - public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecardName) + public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard) { CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance"); - return SaveAppearanceToNotecard(avatarId, notecardName); + return SaveAppearanceToNotecard(avatarId, notecard); } - protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecardName) + protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecard) { IAvatarFactory appearanceModule = World.RequestModuleInterface(); @@ -2382,7 +2382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api OSDMap appearancePacked = sp.Appearance.Pack(); TaskInventoryItem item - = SaveNotecard(notecardName, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); + = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); return new LSL_Key(item.AssetID.ToString()); } @@ -2392,23 +2392,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecardName) + protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecard) { ScenePresence sp = World.GetScenePresence(avatarId); if (sp == null || sp.IsChildAgent) return new LSL_Key(UUID.Zero.ToString()); - return SaveAppearanceToNotecard(sp, notecardName); + return SaveAppearanceToNotecard(sp, notecard); } - protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecardName) + protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecard) { UUID avatarId; if (!UUID.TryParse(rawAvatarId, out avatarId)) return new LSL_Key(UUID.Zero.ToString()); - return SaveAppearanceToNotecard(avatarId, notecardName); + return SaveAppearanceToNotecard(avatarId, notecard); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 1f3454f..87cfe1a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -168,9 +168,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); - key osNpcCreate(string user, string name, vector position, key cloneFrom); - LSL_Key osNpcSaveAppearance(key npc, string notecardName); - void osNpcLoadAppearance(key npc, string notecardNameOrUuid); + key osNpcCreate(string user, string name, vector position, string notecard); + LSL_Key osNpcSaveAppearance(key npc, string notecard); + void osNpcLoadAppearance(key npc, string notecard); vector osNpcGetPos(key npc); void osNpcMoveTo(key npc, vector position); void osNpcMoveToTarget(key npc, vector target, int options); @@ -180,8 +180,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcSay(key npc, string message); void osNpcRemove(key npc); - LSL_Key osOwnerSaveAppearance(string notecardName); - LSL_Key osAgentSaveAppearance(key agentId, string notecardName); + LSL_Key osOwnerSaveAppearance(string notecard); + LSL_Key osAgentSaveAppearance(key agentId, string notecard); key osGetMapTexture(); key osGetRegionMapTexture(string regionName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 13cf7fa..bbc8cc6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -483,14 +483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); } - public key osNpcSaveAppearance(key npc, string notecardName) + public key osNpcSaveAppearance(key npc, string notecard) { - return m_OSSL_Functions.osNpcSaveAppearance(npc, notecardName); + return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard); } - public void osNpcLoadAppearance(key npc, string notecardNameOrUuid) + public void osNpcLoadAppearance(key npc, string notecard) { - m_OSSL_Functions.osNpcLoadAppearance(npc, notecardNameOrUuid); + m_OSSL_Functions.osNpcLoadAppearance(npc, notecard); } public vector osNpcGetPos(LSL_Key npc) @@ -533,14 +533,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcRemove(npc); } - public LSL_Key osOwnerSaveAppearance(string notecardName) + public LSL_Key osOwnerSaveAppearance(string notecard) { - return m_OSSL_Functions.osOwnerSaveAppearance(notecardName); + return m_OSSL_Functions.osOwnerSaveAppearance(notecard); } - public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecardName) + public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecard) { - return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecardName); + return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecard); } public OSSLPrim Prim; -- cgit v1.1 From 4b88f04c0afd36f9e88680bbafb7ccc4680fd504 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 22:46:42 +0100 Subject: minor: On "login disable/enable" always tell the user the final login status, rather than remaining silent if it was already on/off --- OpenSim/Region/CoreModules/World/Access/AccessModule.cs | 6 ++---- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs index c355b13..b5e1fd9 100644 --- a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs +++ b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs @@ -129,13 +129,11 @@ namespace OpenSim.Region.CoreModules.World switch (cmd[1]) { case "enable": - if (scene.LoginsDisabled) - MainConsole.Instance.Output(String.Format("Enabling logins for region {0}", scene.RegionInfo.RegionName)); + MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName)); scene.LoginsDisabled = false; break; case "disable": - if (!scene.LoginsDisabled) - MainConsole.Instance.Output(String.Format("Disabling logins for region {0}", scene.RegionInfo.RegionName)); + MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName)); scene.LoginsDisabled = true; break; case "status": diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index c764c20..11fda6d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -105,9 +105,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC } else { - m_log.DebugFormat( - "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}", - presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); +// m_log.DebugFormat( +// "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}", +// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); Vector3 agent_control_v3 = new Vector3(); presence.HandleMoveToTargetUpdate(ref agent_control_v3); -- cgit v1.1 From ed142ead25834f6ce77585262a69f873db03a393 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 22:50:58 +0100 Subject: minor: change login enable/disable messages in last commit so that they occur after the setting has been made --- OpenSim/Region/CoreModules/World/Access/AccessModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs index b5e1fd9..2399134 100644 --- a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs +++ b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs @@ -129,12 +129,12 @@ namespace OpenSim.Region.CoreModules.World switch (cmd[1]) { case "enable": - MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName)); scene.LoginsDisabled = false; + MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName)); break; case "disable": - MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName)); scene.LoginsDisabled = true; + MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName)); break; case "status": if (scene.LoginsDisabled) -- cgit v1.1 From 78ff82bfe9728b83a56e315522ee33961abe9a9d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Aug 2011 23:40:22 +0100 Subject: If a map request to a server fails, always close the outbound connection. This probably doesn't help with the current memory leak. --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index fac2dab..7b00597 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -682,7 +682,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send os = mapitemsrequest.GetRequestStream(); os.Write(buffer, 0, buffer.Length); //Send it - os.Close(); //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver); } catch (WebException ex) @@ -705,6 +704,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap responseMap["connect"] = OSD.FromBoolean(false); return responseMap; } + finally + { + if (os != null) + os.Close(); + } string response_mapItems_reply = null; { // get the response -- cgit v1.1 From 90c6fa89bea62f97376222f8251d576fa9af1298 Mon Sep 17 00:00:00 2001 From: Aaron Duffy Date: Sat, 6 Aug 2011 22:34:41 -0600 Subject: Fix a bug preventing region modules from creating trees at anything but the default scale. --- OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs index c2ad7b8..ab8e1bf 100644 --- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs +++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs @@ -100,15 +100,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation { case Tree.Cypress1: case Tree.Cypress2: - tree.Scale = new Vector3(4, 4, 10); + tree.Scale *= new Vector3(8, 8, 20); break; // case... other tree types - // tree.Scale = new Vector3(?, ?, ?); + // tree.Scale *= new Vector3(?, ?, ?); // break; default: - tree.Scale = new Vector3(4, 4, 4); + tree.Scale *= new Vector3(8, 8, 8); break; } } -- cgit v1.1 From dcb4b2de09032380fb428f73d9e3fd10aa662377 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 13 Aug 2011 15:16:43 +0100 Subject: Fix a problem in the Flotsam asset cache where assets were being put into the memory cache even when it wasn't enabled. This hopefully addresses http://opensimulator.org/mantis/view.php?id=5634 This is the most probable cause of the memory problems that people have been seeing in the past month. This bug has been around since commit 5dc785b (4th July 2011). Doh! This is why regressions tests are such a good idea... :) Many thanks to Nebadon for using git bisect to track down this bug, which made it a 5 minute fix. --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 7ef759c..abfc771 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -357,8 +357,6 @@ namespace Flotsam.RegionModules.AssetCache asset = (AssetBase)bformatter.Deserialize(stream); - UpdateMemoryCache(id, asset); - m_DiskHits++; } catch (System.Runtime.Serialization.SerializationException e) @@ -419,9 +417,15 @@ namespace Flotsam.RegionModules.AssetCache if (m_MemoryCacheEnabled) asset = GetFromMemoryCache(id); + if (asset == null && m_FileCacheEnabled) + { asset = GetFromFileCache(id); + if (m_MemoryCacheEnabled && asset != null) + UpdateMemoryCache(id, asset); + } + if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) { m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; -- cgit v1.1 From b80dfb6572438cb583e95884c0f607342f0c88d4 Mon Sep 17 00:00:00 2001 From: Micheil Merlin Date: Fri, 12 Aug 2011 21:09:01 -0500 Subject: llGetPrimitiveParams fix prim hollow/hole shape value --- .../Shared/Api/Implementation/LSL_Api.cs | 6 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 175 +++++++++++++++++++++ 2 files changed, 178 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8a281d4..c84afee 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7650,7 +7650,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.PRIM_TYPE_BOX: case ScriptBaseClass.PRIM_TYPE_CYLINDER: case ScriptBaseClass.PRIM_TYPE_PRISM: - res.Add(new LSL_Integer(Shape.ProfileCurve)); + res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); @@ -7659,7 +7659,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case ScriptBaseClass.PRIM_TYPE_SPHERE: - res.Add(new LSL_Integer(Shape.ProfileCurve)); + res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); @@ -7675,7 +7675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.PRIM_TYPE_TUBE: case ScriptBaseClass.PRIM_TYPE_TORUS: // holeshape - res.Add(new LSL_Integer(Shape.ProfileCurve)); + res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. // cut res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 3f37ec7..623c82d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -27,11 +27,13 @@ using System.Collections.Generic; using NUnit.Framework; +using OpenSim.Framework; using OpenSim.Tests.Common; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.Framework.Scenes; using Nini.Config; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenMetaverse; using System; using OpenSim.Tests.Common.Mock; @@ -47,6 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; + private const double FLOAT_ACCURACY = 0.00005d; private LSL_Api m_lslApi; [SetUp] @@ -166,6 +169,178 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests } [Test] + // llSetPrimitiveParams and llGetPrimitiveParams test. + public void TestllSetPrimitiveParams() + { + // Create Prim1. + Scene scene = SceneHelpers.SetupScene(); + string obj1Name = "Prim1"; + UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); + SceneObjectPart part1 = + new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, + Vector3.Zero, Quaternion.Identity, + Vector3.Zero) { Name = obj1Name, UUID = objUuid }; + Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True); + + // Test a sphere. + CheckllSetPrimitiveParams( + "test 1", // Prim test identification string + new LSL_Types.Vector3(6.0d, 9.9d, 9.9d), // Prim size + ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type + ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type + new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut + 0.80d, // Prim hollow + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist + new LSL_Types.Vector3(0.32d, 0.76d, 0.0d)); // Prim dimple + + // Test a prism. + CheckllSetPrimitiveParams( + "test 2", // Prim test identification string + new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size + ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type + ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type + new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut + 0.90d, // Prim hollow + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist + new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d)); // Prim shear + + // Test a box. + CheckllSetPrimitiveParams( + "test 3", // Prim test identification string + new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size + ScriptBaseClass.PRIM_TYPE_BOX, // Prim type + ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type + new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut + 0.90d, // Prim hollow + new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist + new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d)); // Prim shear + + // Test a tube. + CheckllSetPrimitiveParams( + "test 4", // Prim test identification string + new LSL_Types.Vector3(4.2d, 4.2d, 4.2d), // Prim size + ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type + ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type + new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut + 0.00d, // Prim hollow + new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist + new LSL_Types.Vector3(1.0d, 0.5d, 0.0d), // Prim hole size + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear + new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut + new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper + 1.0d, // Prim revolutions + 1.0d, // Prim radius + 0.0d); // Prim skew + } + + // Set prim params for a box, cylinder or prism and check results. + public void CheckllSetPrimitiveParams(string primTest, + LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, + double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear) + { + // Set the prim params. + m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, + ScriptBaseClass.PRIM_TYPE, primType, primHoleType, + primCut, primHollow, primTwist, primTaper, primShear)); + + // Get params for prim to validate settings. + LSL_Types.list primParams = + m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE)); + + // Validate settings. + CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size"); + Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1), + "TestllSetPrimitiveParams " + primTest + " prim type check fail"); + Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2), + "TestllSetPrimitiveParams " + primTest + " prim hole default check fail"); + CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut"); + Assert.AreEqual(primHollow, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, + "TestllSetPrimitiveParams " + primTest + " prim hollow check fail"); + CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist"); + CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 6), primTest + " prim taper"); + CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear"); + } + + // Set prim params for a sphere and check results. + public void CheckllSetPrimitiveParams(string primTest, + LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, + double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple) + { + // Set the prim params. + m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, + ScriptBaseClass.PRIM_TYPE, primType, primHoleType, + primCut, primHollow, primTwist, primDimple)); + + // Get params for prim to validate settings. + LSL_Types.list primParams = + m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE)); + + // Validate settings. + CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size"); + Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1), + "TestllSetPrimitiveParams " + primTest + " prim type check fail"); + Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2), + "TestllSetPrimitiveParams " + primTest + " prim hole default check fail"); + CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut"); + Assert.AreEqual(primHollow, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, + "TestllSetPrimitiveParams " + primTest + " prim hollow check fail"); + CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist"); + CheckllSetPrimitiveParamsVector(primDimple, m_lslApi.llList2Vector(primParams, 6), primTest + " prim dimple"); + } + + // Set prim params for a torus, tube or ring and check results. + public void CheckllSetPrimitiveParams(string primTest, + LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, + double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize, + LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper, + double primRev, double primRadius, double primSkew) + { + // Set the prim params. + m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, + ScriptBaseClass.PRIM_TYPE, primType, primHoleType, + primCut, primHollow, primTwist, primHoleSize, primShear, primProfCut, + primTaper, primRev, primRadius, primSkew)); + + // Get params for prim to validate settings. + LSL_Types.list primParams = + m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE)); + + // Valdate settings. + CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size"); + Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1), + "TestllSetPrimitiveParams " + primTest + " prim type check fail"); + Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2), + "TestllSetPrimitiveParams " + primTest + " prim hole default check fail"); + CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut"); + Assert.AreEqual(primHollow, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, + "TestllSetPrimitiveParams " + primTest + " prim hollow check fail"); + CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist"); + CheckllSetPrimitiveParamsVector(primHoleSize, m_lslApi.llList2Vector(primParams, 6), primTest + " prim hole size"); + CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear"); + CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut"); + CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper"); + Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY, + "TestllSetPrimitiveParams " + primTest + " prim revolution fail"); + Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY, + "TestllSetPrimitiveParams " + primTest + " prim radius fail"); + Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY, + "TestllSetPrimitiveParams " + primTest + " prim skew fail"); + } + + public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg) + { + // Check each vector component against expected result. + Assert.AreEqual(vecCheck.x, vecReturned.x, VECTOR_COMPONENT_ACCURACY, + "TestllSetPrimitiveParams " + msg + " vector check fail on x component"); + Assert.AreEqual(vecCheck.y, vecReturned.y, VECTOR_COMPONENT_ACCURACY, + "TestllSetPrimitiveParams " + msg + " vector check fail on y component"); + Assert.AreEqual(vecCheck.z, vecReturned.z, VECTOR_COMPONENT_ACCURACY, + "TestllSetPrimitiveParams " + msg + " vector check fail on z component"); + } + + [Test] // llVecNorm test. public void TestllVecNorm() { -- cgit v1.1 From e19843a0ee6deb1f9f96a954c97c011b3110aac0 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Sun, 14 Aug 2011 17:45:23 +0200 Subject: WorldMap: Added map item for Land-for-Sale. Implemented backlist item timeouts (default 10 minutes; see also new config file setting BlacklistTimeout) and removing backlisted neigboring regions that have been restarted from the blacklist. --- .../CoreModules/World/WorldMap/WorldMapModule.cs | 206 +++++++++++++++++++-- 1 file changed, 187 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 7b00597..710230a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -46,6 +46,7 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.CoreModules.World.Land; using Caps=OpenSim.Framework.Capabilities.Caps; using OSDArray=OpenMetaverse.StructuredData.OSDArray; using OSDMap=OpenMetaverse.StructuredData.OSDMap; @@ -68,6 +69,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap protected Scene m_scene; private List cachedMapBlocks = new List(); private int cachedTime = 0; + private int blacklistTimeout = 10*60*1000; // 10 minutes private byte[] myMapImageJPEG; protected volatile bool m_Enabled = false; private Dictionary m_openRequests = new Dictionary(); @@ -85,6 +87,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap IConfig startupConfig = config.Configs["Startup"]; if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap") m_Enabled = true; + + blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000; } public virtual void AddRegion (Scene scene) @@ -159,11 +163,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_scene.EventManager.OnClientClosed += ClientLoggedOut; m_scene.EventManager.OnMakeChildAgent += MakeChildAgent; m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; + m_scene.EventManager.OnRegionUp += OnRegionUp; + + StartThread(new object()); } // this has to be called with a lock on m_scene protected virtual void RemoveHandlers() { + StopThread(); + + m_scene.EventManager.OnRegionUp -= OnRegionUp; m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent; m_scene.EventManager.OnClientClosed -= ClientLoggedOut; @@ -279,7 +289,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap /// public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) { - m_log.Debug("[WORLD MAP]: MapLayer Request in region: " + m_scene.RegionInfo.RegionName); + m_log.DebugFormat("[WORLD MAP]: MapLayer Request in region: {0}", m_scene.RegionInfo.RegionName); LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); return mapResponse; @@ -321,8 +331,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap lock (m_rootAgents) { m_rootAgents.Remove(AgentId); - if (m_rootAgents.Count == 0) - StopThread(); } } #endregion @@ -362,6 +370,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { +// m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype); + lock (m_rootAgents) { if (!m_rootAgents.Contains(remoteClient.AgentId)) @@ -370,7 +380,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap uint xstart = 0; uint ystart = 0; Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); - if (itemtype == 6) // we only sevice 6 right now (avatar green dots) + if (itemtype == 6) // Service 6 right now (MAP_ITEM_AGENTS_LOCATION; green dots) { if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) { @@ -414,14 +424,58 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // Remote Map Item Request // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. - // Note that we only start up a remote mapItem Request thread if there's users who could - // be making requests - if (!threadrunning) + RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); + } + } else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE) + { + if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) + { + // Parcels + ILandChannel landChannel = m_scene.LandChannel; + List parcels = landChannel.AllParcels(); + + // Local Map Item Request + int tc = Environment.TickCount; + List mapitems = new List(); + mapItemReply mapitem = new mapItemReply(); + if ((parcels != null) && (parcels.Count >= 1)) { - m_log.Warn("[WORLD MAP]: Starting new remote request thread manually. This means that AvatarEnteringParcel never fired! This needs to be fixed! Don't Mantis this, as the developers can see it in this message"); - StartThread(new object()); + foreach (ILandObject parcel_interface in parcels) + { + // Play it safe + if (!(parcel_interface is LandObject)) + continue; + + LandObject land = (LandObject)parcel_interface; + LandData parcel = land.LandData; + + // Show land for sale + if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale) + { + Vector3 min = parcel.AABBMin; + Vector3 max = parcel.AABBMax; + float x = (min.X+max.X)/2; + float y = (min.Y+max.Y)/2; + + mapitem = new mapItemReply(); + mapitem.x = (uint)(xstart + x); + mapitem.y = (uint)(ystart + y); + // mapitem.z = (uint)m_scene.GetGroundHeight(x,y); + mapitem.id = UUID.Zero; + mapitem.name = parcel.Name; + mapitem.Extra = parcel.Area; + mapitem.Extra2 = parcel.SalePrice; + mapitems.Add(mapitem); + } + } } + remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); + } + else + { + // Remote Map Item Request + // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); } } @@ -542,6 +596,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); } + + // Service 7 (MAP_ITEM_LAND_FOR_SALE) + uint itemtype = 7; + + if (response.ContainsKey(itemtype.ToString())) + { + List returnitems = new List(); + OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; + for (int i = 0; i < itemarray.Count; i++) + { + OSDMap mapitem = (OSDMap)itemarray[i]; + mapItemReply mi = new mapItemReply(); + mi.x = (uint)mapitem["X"].AsInteger(); + mi.y = (uint)mapitem["Y"].AsInteger(); + mi.id = mapitem["ID"].AsUUID(); + mi.Extra = mapitem["Extra"].AsInteger(); + mi.Extra2 = mapitem["Extra2"].AsInteger(); + mi.name = mapitem["Name"].AsString(); + returnitems.Add(mi); + } + av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); + } } } } @@ -589,12 +665,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private OSDMap RequestMapItemsAsync(UUID id, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { +// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); + string httpserver = ""; bool blacklisted = false; lock (m_blacklistedregions) { if (m_blacklistedregions.ContainsKey(regionhandle)) - blacklisted = true; + { + if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout)) + { + m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle); + + m_blacklistedregions.Remove(regionhandle); + } + else + blacklisted = true; + } } if (blacklisted) @@ -636,7 +723,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap lock (m_blacklistedurls) { if (m_blacklistedurls.ContainsKey(httpserver)) - blacklisted = true; + { + if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout)) + { + m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver); + + m_blacklistedurls.Remove(httpserver); + } + else + blacklisted = true; + } } // Can't find the http server @@ -1064,6 +1160,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); + // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots) + OSDMap responsemap = new OSDMap(); int tc = Environment.TickCount; if (m_scene.GetRootAgentCount() == 0) @@ -1096,6 +1194,60 @@ namespace OpenSim.Region.CoreModules.World.WorldMap }); responsemap["6"] = responsearr; } + + // Service 7 (MAP_ITEM_LAND_FOR_SALE) + + ILandChannel landChannel = m_scene.LandChannel; + List parcels = landChannel.AllParcels(); + + if ((parcels == null) || (parcels.Count == 0)) + { + OSDMap responsemapdata = new OSDMap(); + responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1)); + responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1)); + responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); + responsemapdata["Name"] = OSD.FromString(""); + responsemapdata["Extra"] = OSD.FromInteger(0); + responsemapdata["Extra2"] = OSD.FromInteger(0); + OSDArray responsearr = new OSDArray(); + responsearr.Add(responsemapdata); + + responsemap["7"] = responsearr; + } + else + { + OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); + foreach (ILandObject parcel_interface in parcels) + { + // Play it safe + if (!(parcel_interface is LandObject)) + continue; + + LandObject land = (LandObject)parcel_interface; + LandData parcel = land.LandData; + + // Show land for sale + if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale) + { + Vector3 min = parcel.AABBMin; + Vector3 max = parcel.AABBMax; + float x = (min.X+max.X)/2; + float y = (min.Y+max.Y)/2; + + OSDMap responsemapdata = new OSDMap(); + responsemapdata["X"] = OSD.FromInteger((int)(xstart + x)); + responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y)); + // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); + responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); + responsemapdata["Name"] = OSD.FromString(parcel.Name); + responsemapdata["Extra"] = OSD.FromInteger(parcel.Area); + responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice); + responsearr.Add(responsemapdata); + } + } + responsemap["7"] = responsearr; + } + return responsemap; } @@ -1144,12 +1296,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private void MakeRootAgent(ScenePresence avatar) { - // You may ask, why this is in a threadpool to start with.. - // The reason is so we don't cause the thread to freeze waiting - // for the 1 second it costs to start a thread manually. - if (!threadrunning) - Util.FireAndForget(this.StartThread); - lock (m_rootAgents) { if (!m_rootAgents.Contains(avatar.UUID)) @@ -1164,8 +1310,30 @@ namespace OpenSim.Region.CoreModules.World.WorldMap lock (m_rootAgents) { m_rootAgents.Remove(avatar.UUID); - if (m_rootAgents.Count == 0) - StopThread(); + } + } + + public void OnRegionUp(GridRegion otherRegion) + { + ulong regionhandle = otherRegion.RegionHandle; + string httpserver = otherRegion.ServerURI + "MAP/MapItems/" + regionhandle.ToString(); + + lock (m_blacklistedregions) + { + if (!m_blacklistedregions.ContainsKey(regionhandle)) + m_blacklistedregions.Remove(regionhandle); + } + + lock (m_blacklistedurls) + { + if (m_blacklistedurls.ContainsKey(httpserver)) + m_blacklistedurls.Remove(httpserver); + } + + lock (m_cachedRegionMapItemsAddress) + { + if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) + m_cachedRegionMapItemsAddress.Remove(regionhandle); } } -- cgit v1.1 From 9a6ad1535e83a4d1b216ae879173ab8c524da60b Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Mon, 15 Aug 2011 17:46:51 +0200 Subject: Added console command "delete object outside" to delete all objects outside region boundaries. This is especiyll useful in cases where physical objects outside regions boundaries cause much physics engine lag. --- OpenSim/Region/Framework/Scenes/Scene.cs | 39 ++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9aa9bf5..13b4cbc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -611,6 +611,10 @@ namespace OpenSim.Region.Framework.Scenes "delete object name ", "Delete object by name", HandleDeleteObject); + MainConsole.Instance.Commands.AddCommand("region", false, "delete object outside", + "delete object outside", + "Delete all objects outside boundaries", HandleDeleteObject); + //Bind Storage Manager functions to some land manager functions for this scene EventManager.OnLandObjectAdded += new EventManager.LandObjectAdded(simDataService.StoreLandObject); @@ -4941,11 +4945,19 @@ namespace OpenSim.Region.Framework.Scenes private void HandleDeleteObject(string module, string[] cmd) { - if (cmd.Length < 4) + if (cmd.Length < 3) return; string mode = cmd[2]; - string o = cmd[3]; + string o = ""; + + if (mode != "outside") + { + if (cmd.Length < 4) + return; + + o = cmd[3]; + } List deletes = new List(); @@ -4987,10 +4999,33 @@ namespace OpenSim.Region.Framework.Scenes deletes.Add(g); }); break; + case "outside": + ForEachSOG(delegate (SceneObjectGroup g) + { + SceneObjectPart rootPart = g.RootPart; + bool delete = false; + + if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) + { + delete = true; + } else { + ILandObject parcel = LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); + + if (parcel == null || parcel.LandData.Name == "NO LAND") + delete = true; + } + + if (delete && !rootPart.IsAttachment && !deletes.Contains(g)) + deletes.Add(g); + }); + break; } foreach (SceneObjectGroup g in deletes) + { + m_log.InfoFormat("[SCENE]: Deleting object {0}", g.UUID); DeleteSceneObject(g, false); + } } private void HandleReloadEstate(string module, string[] cmd) -- cgit v1.1 From 0784791a44d5f5b7db7c3d2534cc158160819d01 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 15 Aug 2011 16:21:04 -0400 Subject: Add "shutdown" message to RegionReady Add "shutdown" message when removing region. From a patch submitted by Michelle Argus. Thanks Michelle --- .../OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index 05c729a..963d1e2 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -126,6 +126,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; + if(m_uri != string.Empty) + { + RRAlert("shutdown"); + } + m_scene = null; } -- cgit v1.1 From 8c95c83562db7e273cbf555514224773f21a2b19 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 21:03:43 +0100 Subject: On Flotsam asset cache, go back to moving the file from the temporary location rather than copying. Copying doesn't prevent IOExceptions on Windows due to file locking. (e.g. Mantis 5642, 5630). So instead go back to moving the file, swallowing IOExceptions that occur just for the move due to competing caching threads or even different opensimulator instances. --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 73 ++++++++++++++-------- 1 file changed, 47 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index abfc771..b2f6e13 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -593,39 +593,60 @@ namespace Flotsam.RegionModules.AssetCache try { - if (!Directory.Exists(directory)) + try { - Directory.CreateDirectory(directory); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + stream = File.Open(tempname, FileMode.Create); + BinaryFormatter bformatter = new BinaryFormatter(); + bformatter.Serialize(stream, asset); } + catch (IOException e) + { + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.", + asset.ID, tempname, filename, directory, e.Message, e.StackTrace); - stream = File.Open(tempname, FileMode.Create); - BinaryFormatter bformatter = new BinaryFormatter(); - bformatter.Serialize(stream, asset); - stream.Close(); - - // Now that it's written, rename it so that it can be found. - // We're doing this as a file copy operation so that if two threads are competing to cache this asset, - // then both suceed instead of one failing when it tries to move the file to a final filename that - // already exists. - // This assumes that the file copy operation is atomic. Assuming this holds, then copying also works - // if another simulator is using the same cache directory. - File.Copy(tempname, filename, true); - File.Delete(tempname); + return; + } + finally + { + if (stream != null) + stream.Close(); + } - if (m_LogLevel >= 2) - m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to cache. Directory {1}, tempname {2}, filename {3}. Exception {4} {5}.", - asset.ID, directory, tempname, filename, e.Message, e.StackTrace); + try + { + // Now that it's written, rename it so that it can be found. + // + // File.Copy(tempname, filename, true); + // File.Delete(tempname); + // + // For a brief period, this was done as a separate copy and then temporary file delete operation. + // However, this causes exceptions on Windows when other threads attempt to read a file + // which is still being copied. So instead, go back to moving the file and swallowing any IOException + // that occurs because two threads race to cache the same data (and the second fails because the file + // already exists). + // + // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the + // filesystem. + File.Move(tempname, filename); + + if (m_LogLevel >= 2) + m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); + } + catch (IOException) + { + // If we see an IOException here it's likely that some other competing thread has written the + // cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be + // signally by the earlier temporary file writing code. + } } finally { - if (stream != null) - stream.Close(); - // Even if the write fails with an exception, we need to make sure // that we release the lock on that file, otherwise it'll never get // cached -- cgit v1.1 From fd3a7ab70c04742a8ea776180144ea016e0d4e31 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 21:31:08 +0100 Subject: minor: change some comment text in flotsam asset cache --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index b2f6e13..22c301b 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -625,11 +625,10 @@ namespace Flotsam.RegionModules.AssetCache // File.Copy(tempname, filename, true); // File.Delete(tempname); // - // For a brief period, this was done as a separate copy and then temporary file delete operation. + // For a brief period, this was done as a separate copy and then temporary file delete operation to + // avoid an IOException caused by move if some competing thread had already written the file. // However, this causes exceptions on Windows when other threads attempt to read a file - // which is still being copied. So instead, go back to moving the file and swallowing any IOException - // that occurs because two threads race to cache the same data (and the second fails because the file - // already exists). + // which is still being copied. So instead, go back to moving the file and swallow any IOException. // // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the // filesystem. -- cgit v1.1 From 8d866ae8c3e2c866f8b4b905d5a74370042100c3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 21:45:01 +0100 Subject: minor: remove some mono compiler warnings --- OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | 6 +++--- OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 22c05c4..e7bd2e7 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -50,8 +50,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetMeshModule : INonSharedRegionModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IAssetService m_AssetService; @@ -113,7 +113,7 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { - UUID capID = UUID.Random(); +// UUID capID = UUID.Random(); //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); if (m_URL == "localhost") diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 24ab06a..fffcee2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -54,8 +54,9 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetTextureModule : INonSharedRegionModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; private IAssetService m_assetService; -- cgit v1.1 From 66eb537d0cedfd017fd8872fb1b60ed15d871d2b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 21:56:56 +0100 Subject: relocate AttachmentTests.cs to AttachmentsModuleTests.cs --- .../Attachments/Tests/AttachmentsModuleTests.cs | 172 +++++++++++++++++++++ .../Framework/Scenes/Tests/AttachmentTests.cs | 172 --------------------- 2 files changed, 172 insertions(+), 172 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs new file mode 100644 index 0000000..cc810d7 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -0,0 +1,172 @@ +/* + * 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 System.Reflection; +using System.Text; +using System.Threading; +using System.Timers; +using Timer=System.Timers.Timer; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests +{ + /// + /// Attachment tests + /// + [TestFixture] + public class AttachmentsModuleTests + { + public Scene scene, scene2; + public UUID agent1; + public static Random random; + public ulong region1, region2; + public AgentCircuitData acd1; + public SceneObjectGroup sog1, sog2, sog3; + + [TestFixtureSetUp] + public void Init() + { + TestHelpers.InMethod(); + + scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); + + ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); + interregionComms.Initialise(new IniConfigSource()); + interregionComms.PostInitialise(); + SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); + SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); + + agent1 = UUID.Random(); + random = new Random(); + sog1 = NewSOG(UUID.Random(), scene, agent1); + sog2 = NewSOG(UUID.Random(), scene, agent1); + sog3 = NewSOG(UUID.Random(), scene, agent1); + + //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); + region1 = scene.RegionInfo.RegionHandle; + region2 = scene2.RegionInfo.RegionHandle; + + SceneHelpers.AddScenePresence(scene, agent1); + } + + [Test] + public void T030_TestAddAttachments() + { + TestHelpers.InMethod(); + + ScenePresence presence = scene.GetScenePresence(agent1); + + presence.AddAttachment(sog1); + presence.AddAttachment(sog2); + presence.AddAttachment(sog3); + + Assert.That(presence.HasAttachments(), Is.True); + Assert.That(presence.ValidateAttachments(), Is.True); + } + + [Test] + public void T031_RemoveAttachments() + { + TestHelpers.InMethod(); + + ScenePresence presence = scene.GetScenePresence(agent1); + presence.RemoveAttachment(sog1); + presence.RemoveAttachment(sog2); + presence.RemoveAttachment(sog3); + Assert.That(presence.HasAttachments(), Is.False); + } + + // I'm commenting this test because scene setup NEEDS InventoryService to + // be non-null + //[Test] + public void T032_CrossAttachments() + { + TestHelpers.InMethod(); + + ScenePresence presence = scene.GetScenePresence(agent1); + ScenePresence presence2 = scene2.GetScenePresence(agent1); + presence2.AddAttachment(sog1); + presence2.AddAttachment(sog2); + + ISharedRegionModule serialiser = new SerialiserModule(); + SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser); + SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser); + + Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross"); + + //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful"); + Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted"); + Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); + } + + private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent) + { + SceneObjectPart sop = new SceneObjectPart(); + sop.Name = RandomName(); + sop.Description = RandomName(); + sop.Text = RandomName(); + sop.SitName = RandomName(); + sop.TouchName = RandomName(); + sop.UUID = uuid; + sop.Shape = PrimitiveBaseShape.Default; + sop.Shape.State = 1; + sop.OwnerID = agent; + + SceneObjectGroup sog = new SceneObjectGroup(sop); + sog.SetScene(scene); + + return sog; + } + + private static string RandomName() + { + StringBuilder name = new StringBuilder(); + int size = random.Next(5,12); + char ch; + for (int i = 0; i < size; i++) + { + ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ; + name.Append(ch); + } + + return name.ToString(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs deleted file mode 100644 index 07b30f4..0000000 --- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 System.Reflection; -using System.Text; -using System.Threading; -using System.Timers; -using Timer=System.Timers.Timer; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.CoreModules.World.Serialiser; -using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.Framework.Scenes.Tests -{ - /// - /// Attachment tests - /// - [TestFixture] - public class AttachmentTests - { - public Scene scene, scene2; - public UUID agent1; - public static Random random; - public ulong region1, region2; - public AgentCircuitData acd1; - public SceneObjectGroup sog1, sog2, sog3; - - [TestFixtureSetUp] - public void Init() - { - TestHelpers.InMethod(); - - scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); - - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - interregionComms.Initialise(new IniConfigSource()); - interregionComms.PostInitialise(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); - - agent1 = UUID.Random(); - random = new Random(); - sog1 = NewSOG(UUID.Random(), scene, agent1); - sog2 = NewSOG(UUID.Random(), scene, agent1); - sog3 = NewSOG(UUID.Random(), scene, agent1); - - //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - region1 = scene.RegionInfo.RegionHandle; - region2 = scene2.RegionInfo.RegionHandle; - - SceneHelpers.AddScenePresence(scene, agent1); - } - - [Test] - public void T030_TestAddAttachments() - { - TestHelpers.InMethod(); - - ScenePresence presence = scene.GetScenePresence(agent1); - - presence.AddAttachment(sog1); - presence.AddAttachment(sog2); - presence.AddAttachment(sog3); - - Assert.That(presence.HasAttachments(), Is.True); - Assert.That(presence.ValidateAttachments(), Is.True); - } - - [Test] - public void T031_RemoveAttachments() - { - TestHelpers.InMethod(); - - ScenePresence presence = scene.GetScenePresence(agent1); - presence.RemoveAttachment(sog1); - presence.RemoveAttachment(sog2); - presence.RemoveAttachment(sog3); - Assert.That(presence.HasAttachments(), Is.False); - } - - // I'm commenting this test because scene setup NEEDS InventoryService to - // be non-null - //[Test] - public void T032_CrossAttachments() - { - TestHelpers.InMethod(); - - ScenePresence presence = scene.GetScenePresence(agent1); - ScenePresence presence2 = scene2.GetScenePresence(agent1); - presence2.AddAttachment(sog1); - presence2.AddAttachment(sog2); - - ISharedRegionModule serialiser = new SerialiserModule(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser); - - Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross"); - - //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful"); - Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted"); - Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); - } - - private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent) - { - SceneObjectPart sop = new SceneObjectPart(); - sop.Name = RandomName(); - sop.Description = RandomName(); - sop.Text = RandomName(); - sop.SitName = RandomName(); - sop.TouchName = RandomName(); - sop.UUID = uuid; - sop.Shape = PrimitiveBaseShape.Default; - sop.Shape.State = 1; - sop.OwnerID = agent; - - SceneObjectGroup sog = new SceneObjectGroup(sop); - sog.SetScene(scene); - - return sog; - } - - private static string RandomName() - { - StringBuilder name = new StringBuilder(); - int size = random.Next(5,12); - char ch; - for (int i = 0; i < size; i++) - { - ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ; - name.Append(ch); - } - - return name.ToString(); - } - } -} \ No newline at end of file -- cgit v1.1 From 601257f8b6ff7ad97f62e0ab2a428912095bf6dc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 21:58:52 +0100 Subject: remove setting up of second scene in attachments since it's not currently used --- .../Attachments/Tests/AttachmentsModuleTests.cs | 45 ++++++++++------------ 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index cc810d7..b008499 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -52,10 +52,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [TestFixture] public class AttachmentsModuleTests { - public Scene scene, scene2; + public Scene scene; public UUID agent1; public static Random random; - public ulong region1, region2; + public ulong region1; public AgentCircuitData acd1; public SceneObjectGroup sog1, sog2, sog3; @@ -65,13 +65,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); interregionComms.Initialise(new IniConfigSource()); interregionComms.PostInitialise(); SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); agent1 = UUID.Random(); random = new Random(); @@ -81,7 +79,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); region1 = scene.RegionInfo.RegionHandle; - region2 = scene2.RegionInfo.RegionHandle; SceneHelpers.AddScenePresence(scene, agent1); } @@ -116,25 +113,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // I'm commenting this test because scene setup NEEDS InventoryService to // be non-null //[Test] - public void T032_CrossAttachments() - { - TestHelpers.InMethod(); - - ScenePresence presence = scene.GetScenePresence(agent1); - ScenePresence presence2 = scene2.GetScenePresence(agent1); - presence2.AddAttachment(sog1); - presence2.AddAttachment(sog2); - - ISharedRegionModule serialiser = new SerialiserModule(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser); - - Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross"); - - //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful"); - Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted"); - Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); - } +// public void T032_CrossAttachments() +// { +// TestHelpers.InMethod(); +// +// ScenePresence presence = scene.GetScenePresence(agent1); +// ScenePresence presence2 = scene2.GetScenePresence(agent1); +// presence2.AddAttachment(sog1); +// presence2.AddAttachment(sog2); +// +// ISharedRegionModule serialiser = new SerialiserModule(); +// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser); +// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser); +// +// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross"); +// +// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful"); +// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted"); +// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); +// } private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent) { -- cgit v1.1 From c58b32e7baf199fd2168851a1f718d5650f31423 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 22:09:13 +0100 Subject: drop number of attachments in test from 3 to 2 to reduce text complexity --- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b008499..2e32377 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public static Random random; public ulong region1; public AgentCircuitData acd1; - public SceneObjectGroup sog1, sog2, sog3; + public SceneObjectGroup sog1, sog2; [TestFixtureSetUp] public void Init() @@ -75,7 +75,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests random = new Random(); sog1 = NewSOG(UUID.Random(), scene, agent1); sog2 = NewSOG(UUID.Random(), scene, agent1); - sog3 = NewSOG(UUID.Random(), scene, agent1); //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); region1 = scene.RegionInfo.RegionHandle; @@ -92,7 +91,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests presence.AddAttachment(sog1); presence.AddAttachment(sog2); - presence.AddAttachment(sog3); Assert.That(presence.HasAttachments(), Is.True); Assert.That(presence.ValidateAttachments(), Is.True); @@ -106,7 +104,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests ScenePresence presence = scene.GetScenePresence(agent1); presence.RemoveAttachment(sog1); presence.RemoveAttachment(sog2); - presence.RemoveAttachment(sog3); Assert.That(presence.HasAttachments(), Is.False); } -- cgit v1.1 From 0bbf7c21d719de19d517417523e36bc25ac6ad70 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 22:13:13 +0100 Subject: Isolate existing incomplete attachments tests rather than have them rely on each other. Much easier to debug this way. --- .../Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 2e32377..d182996 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -59,11 +59,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public AgentCircuitData acd1; public SceneObjectGroup sog1, sog2; - [TestFixtureSetUp] + [SetUp] public void Init() { - TestHelpers.InMethod(); - scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); @@ -83,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] - public void T030_TestAddAttachments() + public void TestAddAttachments() { TestHelpers.InMethod(); @@ -97,11 +95,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] - public void T031_RemoveAttachments() + public void TestRemoveAttachments() { TestHelpers.InMethod(); ScenePresence presence = scene.GetScenePresence(agent1); + presence.AddAttachment(sog1); + presence.AddAttachment(sog2); presence.RemoveAttachment(sog1); presence.RemoveAttachment(sog2); Assert.That(presence.HasAttachments(), Is.False); -- cgit v1.1 From d3c10e609e2862165c3a9a4e1f436634191201d3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 22:27:52 +0100 Subject: Move some previously common code back into separate tests. Remove unused region handle from test. --- .../Attachments/Tests/AttachmentsModuleTests.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index d182996..c524090 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -55,7 +55,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public Scene scene; public UUID agent1; public static Random random; - public ulong region1; public AgentCircuitData acd1; public SceneObjectGroup sog1, sog2; @@ -73,11 +72,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests random = new Random(); sog1 = NewSOG(UUID.Random(), scene, agent1); sog2 = NewSOG(UUID.Random(), scene, agent1); - - //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - region1 = scene.RegionInfo.RegionHandle; - - SceneHelpers.AddScenePresence(scene, agent1); } [Test] @@ -85,8 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); - ScenePresence presence = scene.GetScenePresence(agent1); - + ScenePresence presence = SceneHelpers.AddScenePresence(scene, agent1); presence.AddAttachment(sog1); presence.AddAttachment(sog2); @@ -99,14 +92,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); - ScenePresence presence = scene.GetScenePresence(agent1); + ScenePresence presence = SceneHelpers.AddScenePresence(scene, agent1); presence.AddAttachment(sog1); - presence.AddAttachment(sog2); + presence.AddAttachment(sog2); presence.RemoveAttachment(sog1); presence.RemoveAttachment(sog2); Assert.That(presence.HasAttachments(), Is.False); } +// [Test] +// public void TestRezAttachmentsOnAvatarEntrance() +// { +// ScenePresence presence = scene.GetScenePresence(agent1); +// } + // I'm commenting this test because scene setup NEEDS InventoryService to // be non-null //[Test] -- cgit v1.1 From 57e54d84d641787d40a2b45549f6f2d373c5f2f2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 23:05:08 +0100 Subject: Add new FireAndForgetMethod.None. This executes the callback on the same thread that made the request. Designed for use only by regression tests that rely on a predicable event ordering. --- .../Attachments/Tests/AttachmentsModuleTests.cs | 46 ++++++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index c524090..7f25864 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -37,10 +37,11 @@ using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Avatar.Attachments; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -61,18 +62,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [SetUp] public void Init() { - scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.None; - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - interregionComms.Initialise(new IniConfigSource()); - interregionComms.PostInitialise(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); + scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + SceneHelpers.SetupSceneModules(scene, new AttachmentsModule()); agent1 = UUID.Random(); random = new Random(); sog1 = NewSOG(UUID.Random(), scene, agent1); sog2 = NewSOG(UUID.Random(), scene, agent1); - } + } + + [TearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten not to worry about such things. + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } [Test] public void TestAddAttachments() @@ -100,11 +108,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(presence.HasAttachments(), Is.False); } -// [Test] -// public void TestRezAttachmentsOnAvatarEntrance() -// { -// ScenePresence presence = scene.GetScenePresence(agent1); -// } + [Test] + public void TestRezAttachmentsOnAvatarEntrance() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID spId = TestHelpers.ParseTail(0x1); + UUID attItemId = TestHelpers.ParseTail(0x2); + UUID attAssetId = TestHelpers.ParseTail(0x3); + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(spId); + acd.Appearance = new AvatarAppearance(); + acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItemId, attAssetId); + ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); + +// Assert.That(presence.HasAttachments(), Is.True); + } // I'm commenting this test because scene setup NEEDS InventoryService to // be non-null -- cgit v1.1 From d73c42407848edbf7d9c37fab17585fd6038c269 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Aug 2011 23:12:58 +0100 Subject: get rid of logged warnings about lack of some modules - afaik these never occur in real life and just clutter up tests --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 18632d7..90c4706 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1197,10 +1197,6 @@ namespace OpenSim.Region.Framework.Scenes IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); if (m_agentTransfer != null) m_agentTransfer.EnableChildAgents(this); - else - m_log.DebugFormat( - "[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active for region {0}", - m_scene.RegionInfo.RegionName); IFriendsModule friendsModule = m_scene.RequestModuleInterface(); if (friendsModule != null) @@ -2516,13 +2512,7 @@ namespace OpenSim.Region.Framework.Scenes // We have an appearance but we may not have the baked textures. Check the asset cache // to see if all the baked textures are already here. if (m_scene.AvatarFactory != null) - { cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient); - } - else - { - m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); - } // If we aren't using a cached appearance, then clear out the baked textures if (!cachedappearance) -- cgit v1.1 From 696bd448334c89607c95385f05a53e2ab72cb984 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Aug 2011 00:37:33 +0100 Subject: Add new regression TestRezAttachmentsOnAvatarEntrance() to do simple attachments check --- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- .../Attachments/Tests/AttachmentsModuleTests.cs | 22 ++++++++++++++++------ .../InventoryAccess/InventoryAccessModule.cs | 12 ++++++++++++ .../Framework/Scenes/Tests/UserInventoryTests.cs | 8 ++++---- 4 files changed, 33 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ebb5bd2..4dbc5e6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -261,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments false, false, remoteClient.AgentId, true); // m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", +// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", // objatt.Name, remoteClient.Name, AttachmentPt); if (objatt != null) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 7f25864..8c79ab4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -38,6 +38,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Region.CoreModules.Avatar.Attachments; +using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Region.Framework.Scenes; @@ -65,8 +66,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. Util.FireAndForgetMethod = FireAndForgetMethod.None; - scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - SceneHelpers.SetupSceneModules(scene, new AttachmentsModule()); + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); + + scene = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene, config, new AttachmentsModule(), new BasicInventoryAccessModule()); agent1 = UUID.Random(); random = new Random(); @@ -114,16 +119,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID spId = TestHelpers.ParseTail(0x1); + UUID userId = TestHelpers.ParseTail(0x1); UUID attItemId = TestHelpers.ParseTail(0x2); UUID attAssetId = TestHelpers.ParseTail(0x3); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(spId); + UserAccountHelpers.CreateUserWithInventory(scene, userId); + InventoryItemBase attItem + = UserInventoryHelpers.CreateInventoryItem( + scene, "att", attItemId, attAssetId, userId, InventoryType.Object); + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); acd.Appearance = new AvatarAppearance(); - acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItemId, attAssetId); + acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); -// Assert.That(presence.HasAttachments(), Is.True); + Assert.That(presence.HasAttachments(), Is.True); } // I'm commenting this test because scene setup NEEDS InventoryService to diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 4933147..65ba87b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -964,8 +964,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } + else + { + m_log.WarnFormat( + "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", item.AssetID, item.Name, item.ID, remoteClient.Name); + } + return group; } + else + { + m_log.WarnFormat( + "[InventoryAccessModule]: Could not find item {0} for {1} in RezObject()", + itemID, remoteClient.Name); + } return null; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 50b1a48..55fc1e7 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -59,8 +59,8 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); - UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); - UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); @@ -86,8 +86,8 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneHelpers.SetupScene(); - UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); - UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); InventoryFolderBase folder1 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); -- cgit v1.1 From bd5d35ee323df9b15d5303c2dcad7e29a4f3e0eb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Aug 2011 00:42:58 +0100 Subject: extend test to check that there is one attachment and that it has the right name --- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 8c79ab4..5bac4c6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -122,11 +122,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID userId = TestHelpers.ParseTail(0x1); UUID attItemId = TestHelpers.ParseTail(0x2); UUID attAssetId = TestHelpers.ParseTail(0x3); + string attName = "att"; UserAccountHelpers.CreateUserWithInventory(scene, userId); InventoryItemBase attItem = UserInventoryHelpers.CreateInventoryItem( - scene, "att", attItemId, attAssetId, userId, InventoryType.Object); + scene, attName, attItemId, attAssetId, userId, InventoryType.Object); AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); acd.Appearance = new AvatarAppearance(); @@ -134,6 +135,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); Assert.That(presence.HasAttachments(), Is.True); + List attachments = presence.Attachments; + + Assert.That(attachments.Count, Is.EqualTo(1)); + Assert.That(attachments[0].Name, Is.EqualTo(attName)); } // I'm commenting this test because scene setup NEEDS InventoryService to -- cgit v1.1 From acfdca34fd9bf6d66d144ae5c0a325dd5e864517 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Aug 2011 01:35:33 +0100 Subject: Fix issue where loading a new appearance onto an NPC would not remove the previous attachments from the scene. Addresses http://opensimulator.org/mantis/view.php?id=5636 --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 4 ++-- OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | 3 ++- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 4dbc5e6..0316d29 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { - m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); +// m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); try { @@ -466,7 +466,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); - m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); +// m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); // If an item contains scripts, it's always changed. // This ensures script state is saved on detach diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 6cc64c6..4cb3df2 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -96,9 +96,10 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Detach an object from the avatar. /// - /// + /// /// This method is called in response to a client's detach request, so we only update the information in /// inventory + /// /// /// void DetachObject(uint objectLocalID, IClientAPI remoteClient); diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 11fda6d..3b7ae9d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -143,6 +143,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC if (!m_avatars.ContainsKey(agentId)) return false; + // FIXME: An extremely bad bit of code that reaches directly into the attachments list and manipulates it + List attachments = sp.Attachments; + lock (attachments) + { + foreach (SceneObjectGroup att in attachments) + scene.DeleteSceneObject(att, false); + + attachments.Clear(); + } + AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); sp.Appearance = npcAppearance; sp.RezAttachments(); -- cgit v1.1 From 4a9b8184f71197d1270a920b5e4ad85c9de6bed5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Aug 2011 01:51:58 +0100 Subject: For now, supress 'OH NOES' warnings given by HGInventoryBroker.CacheInventoryServiceURL when it tries to cache it for an NPC This concept is meaningless for NPCs. However, it might be better to make NPCism an actual property on ScenePresence and check. Addresses http://opensimulator.org/mantis/view.php?id=5643 --- .../ServiceConnectorsOut/Inventory/HGInventoryBroker.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index 698fd56..72ae3363 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs @@ -211,11 +211,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return; } } - else - { - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID); - return; - } +// else +// { +// m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID); +// return; +// } } } if (sp == null) -- cgit v1.1 From d8f886ccdb6f1bf185e7edaed7cd80b3027d58f2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Aug 2011 23:41:20 +0100 Subject: comment out noisy attachments logging --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 0316d29..a3639e8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -226,9 +226,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public UUID RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) { - m_log.DebugFormat( - "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", - (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", +// (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim @@ -566,8 +566,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { - m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", - so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); +// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", +// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); so.DetachFromBackup(); -- cgit v1.1 From c1a34cd8da293e63d3cba70b5271c9a297789db2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 18 Aug 2011 00:53:05 +0100 Subject: Don't try to save changed attachment states when an NPC with attachments is removed from the scene. This is done by introducing a PresenceType enum into ScenePresence which currently has two values, User and Npc. This seems better than a SaveAttachments flag in terms of code comprehension, though I'm still slightly uneasy about introducing these semantics to core objects --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 4 ++-- OpenSim/Region/Examples/SimpleModule/RegionModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 9 +++++---- OpenSim/Region/Framework/Scenes/SceneBase.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 +++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 +++++++++--- .../Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs | 4 ++-- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 2 +- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 10 files changed, 26 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 1d35973..f71871e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -692,7 +692,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - m_scene.AddNewClient(this); + m_scene.AddNewClient(this, PresenceType.User); RefreshGroupMembership(); } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a3639e8..97a1be6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -501,10 +501,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// Update the attachment asset for the new sog details if they have changed. /// - /// + /// /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, /// these details are not stored on the region. - /// + /// /// /// /// diff --git a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs index 088b818..3b8ce37 100644 --- a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs +++ b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs @@ -95,7 +95,7 @@ namespace OpenSim.Region.Examples.SimpleModule for (int i = 0; i < 1; i++) { MyNpcCharacter m_character = new MyNpcCharacter(m_scene); - m_scene.AddNewClient(m_character); + m_scene.AddNewClient(m_character, PresenceType.Npc); m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 13b4cbc..ae88a87 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2543,10 +2543,11 @@ namespace OpenSim.Region.Framework.Scenes #region Add/Remove Avatar Methods /// - /// Adding a New Client and Create a Presence for it. + /// Add a new client and create a child agent for it. /// /// - public override void AddNewClient(IClientAPI client) + /// The type of agent to add. + public override void AddNewClient(IClientAPI client, PresenceType type) { AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); bool vialogin = false; @@ -2566,7 +2567,7 @@ namespace OpenSim.Region.Framework.Scenes m_clientManager.Add(client); SubscribeToClientEvents(client); - ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance); + ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); m_eventManager.TriggerOnNewPresence(sp); sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags; @@ -3149,7 +3150,7 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnRemovePresence(agentID); - if (avatar != null && (!avatar.IsChildAgent)) + if (avatar != null && (!avatar.IsChildAgent) && avatar.PresenceType != PresenceType.Npc) avatar.SaveChangedAttachments(); ForEachClient( diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 2f1cdc1..ec94f10 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.Framework.Scenes #region Add/Remove Agent/Avatar - public abstract void AddNewClient(IClientAPI client); + public abstract void AddNewClient(IClientAPI client, PresenceType type); public abstract void RemoveClient(UUID agentID, bool closeChildAgents); public bool TryGetScenePresence(UUID agentID, out object scenePresence) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 65dc2c9..f40b373 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -590,12 +590,13 @@ namespace OpenSim.Region.Framework.Scenes } } - protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) + protected internal ScenePresence CreateAndAddChildScenePresence( + IClientAPI client, AvatarAppearance appearance, PresenceType type) { ScenePresence newAvatar = null; // ScenePresence always defaults to child agent - newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); + newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type); AddScenePresence(newAvatar); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 90c4706..e3bd393 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -75,6 +75,11 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// What type of presence is this? User, NPC, etc. + /// + public PresenceType PresenceType { get; private set; } + // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); @@ -715,8 +720,9 @@ namespace OpenSim.Region.Framework.Scenes m_animator = new ScenePresenceAnimator(this); } - private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() + private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, PresenceType type) : this() { + PresenceType = type; m_DrawDistance = world.DefaultDrawDistance; m_rootRegionHandle = reginfo.RegionHandle; m_controllingClient = client; @@ -764,8 +770,8 @@ namespace OpenSim.Region.Framework.Scenes SetDirectionVectors(); } - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) - : this(client, world, reginfo) + public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) + : this(client, world, reginfo, type) { m_appearance = appearance; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index dd2c717..35b41fb 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -207,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests scene.NewUserConnection(acd1, 0, out reason); if (testclient == null) testclient = new TestClient(acd1, scene); - scene.AddNewClient(testclient); + scene.AddNewClient(testclient, PresenceType.User); ScenePresence presence = scene.GetScenePresence(agent1); presence.MakeRootAgent(new Vector3(90,90,90),false); @@ -257,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Adding child agent to region 1001 string reason; scene2.NewUserConnection(acd1,0, out reason); - scene2.AddNewClient(testclient); + scene2.AddNewClient(testclient, PresenceType.User); ScenePresence presence = scene.GetScenePresence(agent1); presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 15201da..c413634 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -893,7 +893,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void Start() { - Scene.AddNewClient(this); + Scene.AddNewClient(this, PresenceType.User); // Mimicking LLClientView which gets always set appearance from client. Scene scene = (Scene)Scene; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 3b7ae9d..c1da803 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -190,7 +190,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC // } scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); - scene.AddNewClient(npcAvatar); + scene.AddNewClient(npcAvatar, PresenceType.Npc); ScenePresence sp; if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) -- cgit v1.1 From 45c37ef494df3e6303a2c0346cb239731d448bed Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 18 Aug 2011 01:11:23 +0100 Subject: refactor: Fold 3 ScenePresence() constructors into one since only one is called. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e3bd393..564a456 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -713,15 +713,12 @@ namespace OpenSim.Region.Framework.Scenes #region Constructor(s) - public ScenePresence() + public ScenePresence( + IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) { m_sendCourseLocationsMethod = SendCoarseLocationsDefault; CreateSceneViewer(); m_animator = new ScenePresenceAnimator(this); - } - - private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, PresenceType type) : this() - { PresenceType = type; m_DrawDistance = world.DefaultDrawDistance; m_rootRegionHandle = reginfo.RegionHandle; @@ -768,11 +765,7 @@ namespace OpenSim.Region.Framework.Scenes RegisterToEvents(); SetDirectionVectors(); - } - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) - : this(client, world, reginfo, type) - { m_appearance = appearance; } -- cgit v1.1 From 49258350e8e34ce36bce08a2f40b8824d67449ab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 18 Aug 2011 01:22:01 +0100 Subject: refactor: fold CreateSceneViewer() back into ScenePresence constructor --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 564a456..719f2da 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -717,7 +717,7 @@ namespace OpenSim.Region.Framework.Scenes IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) { m_sendCourseLocationsMethod = SendCoarseLocationsDefault; - CreateSceneViewer(); + m_sceneViewer = new SceneViewer(this); m_animator = new ScenePresenceAnimator(this); PresenceType = type; m_DrawDistance = world.DefaultDrawDistance; @@ -769,11 +769,6 @@ namespace OpenSim.Region.Framework.Scenes m_appearance = appearance; } - private void CreateSceneViewer() - { - m_sceneViewer = new SceneViewer(this); - } - public void RegisterToEvents() { m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; -- cgit v1.1 From fef73a1a1011126d4df2da2279caae9cef7984d1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 18 Aug 2011 14:32:09 -0700 Subject: BulletSim: add runtime setting of physics parameters. Update default values. --- OpenSim/Region/Framework/Scenes/SceneManager.cs | 7 + .../PhysicsParameters/PhysicsParameters.cs | 277 +++++++++++++++++++++ .../Region/Physics/BulletSPlugin/BSCharacter.cs | 31 ++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 10 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 223 ++++++++++++++++- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 20 +- .../Region/Physics/Manager/IPhysicsParameters.cs | 73 ++++++ 7 files changed, 613 insertions(+), 28 deletions(-) create mode 100755 OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs create mode 100755 OpenSim/Region/Physics/Manager/IPhysicsParameters.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 86ba2aa..97ee844 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -47,6 +47,12 @@ namespace OpenSim.Region.Framework.Scenes public event RestartSim OnRestartSim; + private static SceneManager m_instance = null; + public static SceneManager Instance + { + get { return m_instance; } + } + private readonly List m_localScenes; private Scene m_currentScene = null; @@ -84,6 +90,7 @@ namespace OpenSim.Region.Framework.Scenes public SceneManager() { + m_instance = this; m_localScenes = new List(); } diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs new file mode 100755 index 0000000..2a44360 --- /dev/null +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs @@ -0,0 +1,277 @@ +/* + * 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.Reflection; +using System.Collections.Generic; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.CoreModules.Framework.InterfaceCommander; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.OptionalModules.PhysicsParameters +{ + /// + /// + /// + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")] + public class PhysicsParameters : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[PHYSICS PARAMETERS]"; + + private List m_scenes = new List(); + private static bool m_commandsLoaded = false; + + #region ISharedRegionModule + public string Name { get { return "Runtime Physics Parameter Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { + // m_log.DebugFormat("{0}: INITIALIZED MODULE", LogHeader); + } + + public void PostInitialise() + { + // m_log.DebugFormat("[{0}: POST INITIALIZED MODULE", LogHeader); + InstallInterfaces(); + } + + public void Close() + { + // m_log.DebugFormat("{0}: CLOSED MODULE", LogHeader); + } + + public void AddRegion(Scene scene) + { + // m_log.DebugFormat("{0}: REGION {1} ADDED", LogHeader, scene.RegionInfo.RegionName); + m_scenes.Add(scene); + } + + public void RemoveRegion(Scene scene) + { + // m_log.DebugFormat("{0}: REGION {1} REMOVED", LogHeader, scene.RegionInfo.RegionName); + if (m_scenes.Contains(scene)) + m_scenes.Remove(scene); + } + + public void RegionLoaded(Scene scene) + { + // m_log.DebugFormat("{0}: REGION {1} LOADED", LogHeader, scene.RegionInfo.RegionName); + } + #endregion INonSharedRegionModule + + private const string getInvocation = "physics get [|ALL]"; + private const string setInvocation = "physics set [|TRUE|FALSE] [localID|ALL]"; + private const string listInvocation = "physics list"; + private void InstallInterfaces() + { + if (!m_commandsLoaded) + { + MainConsole.Instance.Commands.AddCommand("Physics", false, "physics set", + "physics set", + "Set physics parameter from currently selected region" + Environment.NewLine + + "Invocation: " + setInvocation, + ProcessPhysicsSet); + + MainConsole.Instance.Commands.AddCommand("Physics", false, "physics get", + "physics get", + "Get physics parameter from currently selected region" + Environment.NewLine + + "Invocation: " + getInvocation, + ProcessPhysicsGet); + + MainConsole.Instance.Commands.AddCommand("Physics", false, "physics list", + "physics list", + "List settable physics parameters" + Environment.NewLine + + "Invocation: " + listInvocation, + ProcessPhysicsList); + + m_commandsLoaded = true; + } + } + + // TODO: extend get so you can get a value from an individual localID + private void ProcessPhysicsGet(string module, string[] cmdparms) + { + if (cmdparms.Length != 3) + { + WriteError("Parameter count error. Invocation: " + getInvocation); + return; + } + string parm = cmdparms[2]; + + if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null) + { + WriteError("Error: no region selected. Use 'change region' to select a region."); + return; + } + + Scene scene = SceneManager.Instance.CurrentScene; + IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; + if (physScene != null) + { + if (parm.ToLower() == "all") + { + foreach (PhysParameterEntry ppe in physScene.GetParameterList()) + { + float val = 0.0f; + if (physScene.GetPhysicsParameter(ppe.name, out val)) + { + WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val); + } + else + { + WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, "unknown"); + } + } + } + else + { + float val = 0.0f; + if (physScene.GetPhysicsParameter(parm, out val)) + { + WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val); + } + else + { + WriteError("Failed fetch of parameter '{0}' from region '{1}'", parm, scene.RegionInfo.RegionName); + } + } + } + else + { + WriteError("Region '{0}' physics engine has no gettable physics parameters", scene.RegionInfo.RegionName); + } + return; + } + + private void ProcessPhysicsSet(string module, string[] cmdparms) + { + if (cmdparms.Length < 4 || cmdparms.Length > 5) + { + WriteError("Parameter count error. Invocation: " + getInvocation); + return; + } + string parm = "xxx"; + float val = 0f; + uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value + try + { + parm = cmdparms[2]; + string valparm = cmdparms[3].ToLower(); + if (valparm == "true") + val = PhysParameterEntry.NUMERIC_TRUE; + else + { + if (valparm == "false") + val = PhysParameterEntry.NUMERIC_FALSE; + else + val = float.Parse(valparm, Culture.NumberFormatInfo); + } + if (cmdparms.Length > 4) + { + if (cmdparms[4].ToLower() == "all") + localID = (uint)PhysParameterEntry.APPLY_TO_ALL; + else + localID = uint.Parse(cmdparms[2], Culture.NumberFormatInfo); + } + } + catch + { + WriteError(" Error parsing parameters. Invocation: " + setInvocation); + return; + } + + if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null) + { + WriteError("Error: no region selected. Use 'change region' to select a region."); + return; + } + + Scene scene = SceneManager.Instance.CurrentScene; + IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; + if (physScene != null) + { + if (!physScene.SetPhysicsParameter(parm, val, localID)) + { + WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName); + } + } + else + { + WriteOut("Region '{0}'s physics engine has no settable physics parameters", scene.RegionInfo.RegionName); + } + return; + } + + private void ProcessPhysicsList(string module, string[] cmdparms) + { + if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null) + { + WriteError("Error: no region selected. Use 'change region' to select a region."); + return; + } + Scene scene = SceneManager.Instance.CurrentScene; + + IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; + if (physScene != null) + { + WriteOut("Available physics parameters:"); + PhysParameterEntry[] parms = physScene.GetParameterList(); + foreach (PhysParameterEntry ent in parms) + { + WriteOut(" {0}: {1}", ent.name, ent.desc); + } + } + else + { + WriteError("Current regions's physics engine has no settable physics parameters"); + } + return; + } + + private void WriteOut(string msg, params object[] args) + { + m_log.InfoFormat(msg, args); + // MainConsole.Instance.OutputFormat(msg, args); + } + + private void WriteError(string msg, params object[] args) + { + m_log.ErrorFormat(msg, args); + // MainConsole.Instance.OutputFormat(msg, args); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 9f9ebcc..682eb80 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -49,8 +49,9 @@ public class BSCharacter : PhysicsActor private bool _grabbed; private bool _selected; private Vector3 _position; - private float _mass = 80f; - public float _density = 60f; + private float _mass; + public float _density; + public float _avatarVolume; private Vector3 _force; private Vector3 _velocity; private Vector3 _torque; @@ -90,13 +91,13 @@ public class BSCharacter : PhysicsActor _scene = parent_scene; _position = pos; _size = size; + _flying = isFlying; _orientation = Quaternion.Identity; _velocity = Vector3.Zero; - _buoyancy = 0f; // characters return a buoyancy of zero + _buoyancy = isFlying ? 1f : 0f; _scale = new Vector3(1f, 1f, 1f); - float AVvolume = (float) (Math.PI*Math.Pow(_scene.Params.avatarCapsuleRadius, 2)*_scene.Params.avatarCapsuleHeight); _density = _scene.Params.avatarDensity; - _mass = _density*AVvolume; + ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale ShapeData shapeData = new ShapeData(); shapeData.ID = _localID; @@ -106,7 +107,7 @@ public class BSCharacter : PhysicsActor shapeData.Velocity = _velocity; shapeData.Scale = _scale; shapeData.Mass = _mass; - shapeData.Buoyancy = isFlying ? 1f : 0f; + shapeData.Buoyancy = _buoyancy; shapeData.Static = ShapeData.numericFalse; shapeData.Friction = _scene.Params.avatarFriction; shapeData.Restitution = _scene.Params.defaultRestitution; @@ -212,6 +213,7 @@ public class BSCharacter : PhysicsActor get { return _velocity; } set { _velocity = value; + // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); _scene.TaintedObject(delegate() { BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); @@ -235,6 +237,7 @@ public class BSCharacter : PhysicsActor get { return _orientation; } set { _orientation = value; + // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); _scene.TaintedObject(delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); @@ -300,7 +303,6 @@ public class BSCharacter : PhysicsActor set { _buoyancy = value; _scene.TaintedObject(delegate() { - // simulate flying by changing the effect of gravity BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); }); } @@ -344,6 +346,7 @@ public class BSCharacter : PhysicsActor _force.X += force.X; _force.Y += force.Y; _force.Z += force.Z; + // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); _scene.TaintedObject(delegate() { BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); @@ -370,6 +373,17 @@ public class BSCharacter : PhysicsActor return (_subscribedEventsMs > 0); } + // set _avatarVolume and _mass based on capsule size, _density and _scale + private void ComputeAvatarVolumeAndMass() + { + _avatarVolume = (float)( + Math.PI + * _scene.Params.avatarCapsuleRadius * _scale.X + * _scene.Params.avatarCapsuleRadius * _scale.Y + * _scene.Params.avatarCapsuleHeight * _scale.Z); + _mass = _density * _avatarVolume; + } + // The physics engine says that properties have updated. Update same and inform // the world that things have changed. public void UpdateProperties(EntityProperties entprop) @@ -403,6 +417,9 @@ public class BSCharacter : PhysicsActor } if (changed) { + // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); + // Avatar movement is not done by generating this event. There is a system that + // checks for avatar updates each heartbeat loop. // base.RequestPhysicsterseUpdate(); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c4999f6..cc414e9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1013,8 +1013,8 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; - // Let the object be scaled by Bullet (the mesh was created as a unit mesh) - _scale = _size; + // meshes are already scaled by the meshmerizer + _scale = new OMV.Vector3(1f, 1f, 1f); } return; } @@ -1138,9 +1138,7 @@ public sealed class BSPrim : PhysicsActor if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh { // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); - // Make the mesh scaled to 1 and use Bullet's scaling feature to scale it in world - OMV.Vector3 scaleFactor = new OMV.Vector3(1.0f, 1.0f, 1.0f); - _mesh = _scene.mesher.CreateMesh(_avName, _pbs, scaleFactor, _scene.MeshLOD, _isPhysical); + _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.MeshLOD, _isPhysical); } else { @@ -1225,6 +1223,8 @@ public sealed class BSPrim : PhysicsActor else { // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. + + // Only updates only for individual prims and for the root object of a linkset. if (this._parentPrim == null) { // Assign to the local variables so the normal set action does not happen diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index de86d59..518be09 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -58,11 +58,13 @@ using OpenSim.Region.Framework; // namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSScene : PhysicsScene +public class BSScene : PhysicsScene, IPhysicsParameters { private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS SCENE]"; + public string BulletSimVersion = "?"; + private Dictionary m_avatars = new Dictionary(); private Dictionary m_prims = new Dictionary(); private List m_vehicles = new List(); @@ -127,7 +129,7 @@ public class BSScene : PhysicsScene ConfigurationParameters[] m_params; GCHandle m_paramsHandle; - private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; + private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; public BSScene(string identifier) { @@ -149,12 +151,17 @@ public class BSScene : PhysicsScene m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + // Get the version of the DLL + // TODO: this doesn't work yet. Something wrong with marshaling the returned string. + // BulletSimVersion = BulletSimAPI.GetVersion(); + // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); + // if Debug, enable logging from the unmanaged code if (m_log.IsDebugEnabled) { m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); - debugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); - BulletSimAPI.SetDebugLogCallback(debugLogCallbackHandle); + m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); + BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); } _taintedObjects = new List(); @@ -188,7 +195,7 @@ public class BSScene : PhysicsScene m_maxUpdatesPerFrame = 2048; m_maximumObjectMass = 10000.01f; - parms.defaultFriction = 0.70f; + parms.defaultFriction = 0.5f; parms.defaultDensity = 10.000006836f; // Aluminum g/cm3 parms.defaultRestitution = 0f; parms.collisionMargin = 0.0f; @@ -202,10 +209,10 @@ public class BSScene : PhysicsScene parms.ccdMotionThreshold = 0.5f; // set to zero to disable parms.ccdSweptSphereRadius = 0.2f; - parms.terrainFriction = 0.85f; - parms.terrainHitFriction = 0.8f; - parms.terrainRestitution = 0.2f; - parms.avatarFriction = 0.85f; + parms.terrainFriction = 0.5f; + parms.terrainHitFraction = 0.8f; + parms.terrainRestitution = 0f; + parms.avatarFriction = 0.0f; parms.avatarDensity = 60f; parms.avatarCapsuleRadius = 0.37f; parms.avatarCapsuleHeight = 1.5f; // 2.140599f @@ -213,7 +220,8 @@ public class BSScene : PhysicsScene if (config != null) { // If there are specifications in the ini file, use those values - // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO ALSO UPDATE OpenSimDefaults.ini + // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO UPDATE OpenSimDefaults.ini + // ALSO REMEMBER TO UPDATE THE RUNTIME SETTING OF THE PARAMETERS. IConfig pConfig = config.Configs["BulletSim"]; if (pConfig != null) { @@ -243,7 +251,7 @@ public class BSScene : PhysicsScene parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); - parms.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", parms.terrainHitFriction); + parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); @@ -386,7 +394,7 @@ public class BSScene : PhysicsScene } } - // FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. + // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; } @@ -651,5 +659,196 @@ public class BSScene : PhysicsScene } } #endregion Vehicles + + #region Runtime settable parameters + public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[] + { + new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (Power of two. Default 32)"), + new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"), + new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"), + new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"), + + new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"), + new PhysParameterEntry("DefaultDensity", "Density for new objects" ), + new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ), + // new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ), + new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ), + + new PhysParameterEntry("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)" ), + new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ), + new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), + new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), + new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), + // new PhysParameterEntry("CcdMotionThreshold", "" ), + // new PhysParameterEntry("CcdSweptSphereRadius", "" ), + + new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), + new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), + new PhysParameterEntry("TerrainRestitution", "Bouncyness" ), + new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ), + new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), + new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), + new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), + new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ) + }; + + #region IPhysicsParameters + // Get the list of parameters this physics engine supports + public PhysParameterEntry[] GetParameterList() + { + return SettableParameters; + } + + // Set parameter on a specific or all instances. + // Return 'false' if not able to set the parameter. + // Setting the value in the m_params block will change the value the physics engine + // will use the next time since it's pinned and shared memory. + // Some of the values require calling into the physics engine to get the new + // value activated ('terrainFriction' for instance). + public bool SetPhysicsParameter(string parm, float val, uint localID) + { + bool ret = true; + string lparm = parm.ToLower(); + switch (lparm) + { + case "meshlod": m_meshLOD = (int)val; break; + case "maxsubstep": m_maxSubSteps = (int)val; break; + case "fixedtimestep": m_fixedTimeStep = val; break; + case "maxobjectmass": m_maximumObjectMass = val; break; + + case "defaultfriction": m_params[0].defaultFriction = val; break; + case "defaultdensity": m_params[0].defaultDensity = val; break; + case "defaultrestitution": m_params[0].defaultRestitution = val; break; + case "collisionmargin": m_params[0].collisionMargin = val; break; + case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break; + + case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; + case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; + case "deactivationtime": UpdateParameterPrims(ref m_params[0].deactivationTime, lparm, localID, val); break; + case "linearsleepingthreshold": UpdateParameterPrims(ref m_params[0].linearSleepingThreshold, lparm, localID, val); break; + case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; + case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; + case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; + + // set a terrain physical feature and cause terrain to be recalculated + case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; + case "terrainhitfraction": m_params[0].terrainHitFraction = val; TaintedUpdateParameter("terrain", 0, val); break; + case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break; + // set an avatar physical feature and cause avatar(s) to be recalculated + case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break; + case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break; + case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; + case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; + case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; + + default: ret = false; break; + } + return ret; + } + + // check to see if we are updating a parameter for a particular or all of the prims + private void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) + { + List operateOn; + lock (m_prims) operateOn = new List(m_prims.Keys); + UpdateParameterSet(operateOn, ref loc, parm, localID, val); + } + + // check to see if we are updating a parameter for a particular or all of the avatars + private void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val) + { + List operateOn; + lock (m_avatars) operateOn = new List(m_avatars.Keys); + UpdateParameterSet(operateOn, ref loc, parm, localID, val); + } + + // update all the localIDs specified + // If the local ID is APPLY_TO_NONE, just change the default value + // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs + // If the localID is a specific object, apply the parameter change to only that object + private void UpdateParameterSet(List lIDs, ref float defaultLoc, string parm, uint localID, float val) + { + switch (localID) + { + case PhysParameterEntry.APPLY_TO_NONE: + defaultLoc = val; // setting only the default value + break; + case PhysParameterEntry.APPLY_TO_ALL: + defaultLoc = val; // setting ALL also sets the default value + List objectIDs = lIDs; + string xparm = parm.ToLower(); + float xval = val; + TaintedObject(delegate() { + foreach (uint lID in objectIDs) + { + BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); + } + }); + break; + default: + // setting only one localID + TaintedUpdateParameter(parm, localID, val); + break; + } + } + + // schedule the actual updating of the paramter to when the phys engine is not busy + private void TaintedUpdateParameter(string parm, uint localID, float val) + { + uint xlocalID = localID; + string xparm = parm.ToLower(); + float xval = val; + TaintedObject(delegate() { + BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); + }); + } + + // Get parameter. + // Return 'false' if not able to get the parameter. + public bool GetPhysicsParameter(string parm, out float value) + { + float val = 0f; + bool ret = true; + switch (parm.ToLower()) + { + case "meshlod": val = (float)m_meshLOD; break; + case "maxsubstep": val = (float)m_maxSubSteps; break; + case "fixedtimestep": val = m_fixedTimeStep; break; + case "maxobjectmass": val = m_maximumObjectMass; break; + + case "defaultfriction": val = m_params[0].defaultFriction; break; + case "defaultdensity": val = m_params[0].defaultDensity; break; + case "defaultrestitution": val = m_params[0].defaultRestitution; break; + case "collisionmargin": val = m_params[0].collisionMargin; break; + case "gravity": val = m_params[0].gravity; break; + + case "lineardamping": val = m_params[0].linearDamping; break; + case "angulardamping": val = m_params[0].angularDamping; break; + case "deactivationtime": val = m_params[0].deactivationTime; break; + case "linearsleepingthreshold": val = m_params[0].linearSleepingThreshold; break; + case "angularsleepingthreshold": val = m_params[0].angularDamping; break; + case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; + case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; + + case "terrainfriction": val = m_params[0].terrainFriction; break; + case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; + case "terrainrestitution": val = m_params[0].terrainRestitution; break; + + case "avatarfriction": val = m_params[0].avatarFriction; break; + case "avatardensity": val = m_params[0].avatarDensity; break; + case "avatarrestitution": val = m_params[0].avatarRestitution; break; + case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break; + case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break; + default: ret = false; break; + + } + value = val; + return ret; + } + + #endregion IPhysicsParameters + + #endregion Runtime settable parameters + } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 819fce1..bf953df 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -51,9 +51,6 @@ public struct ShapeData SHAPE_SPHERE = 4, SHAPE_HULL = 5 }; - // note that bools are passed as ints since bool size changes by language - public const int numericTrue = 1; - public const int numericFalse = 0; public uint ID; public PhysicsShapeType Type; public Vector3 Position; @@ -67,6 +64,10 @@ public struct ShapeData public float Restitution; public int Collidable; public int Static; // true if a static object. Otherwise gravity, etc. + + // note that bools are passed as ints since bool size changes by language and architecture + public const int numericTrue = 1; + public const int numericFalse = 0; } [StructLayout(LayoutKind.Sequential)] public struct SweepHit @@ -121,23 +122,34 @@ public struct ConfigurationParameters public float ccdSweptSphereRadius; public float terrainFriction; - public float terrainHitFriction; + public float terrainHitFraction; public float terrainRestitution; public float avatarFriction; public float avatarDensity; public float avatarRestitution; public float avatarCapsuleRadius; public float avatarCapsuleHeight; + + public const float numericTrue = 1f; + public const float numericFalse = 0f; } static class BulletSimAPI { [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +[return: MarshalAs(UnmanagedType.LPStr)] +public static extern string GetVersion(); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, int maxCollisions, IntPtr collisionArray, int maxUpdates, IntPtr updateArray); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UpdateParameter(uint worldID, uint localID, + [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] diff --git a/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs new file mode 100755 index 0000000..b8676ba --- /dev/null +++ b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs @@ -0,0 +1,73 @@ +/* + * 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 OpenMetaverse; + +namespace OpenSim.Region.Physics.Manager +{ + public struct PhysParameterEntry + { + // flags to say to apply to all or no instances (I wish one could put consts into interfaces) + public const uint APPLY_TO_ALL = 0xfffffff3; + public const uint APPLY_TO_NONE = 0xfffffff4; + + // values that denote true and false values + public const float NUMERIC_TRUE = 1f; + public const float NUMERIC_FALSE = 0f; + + public string name; + public string desc; + + public PhysParameterEntry(string n, string d) + { + name = n; + desc = d; + } + } + + // Interface for a physics scene that implements the runtime setting and getting of physics parameters + public interface IPhysicsParameters + { + // Get the list of parameters this physics engine supports + PhysParameterEntry[] GetParameterList(); + + // Set parameter on a specific or all instances. + // Return 'false' if not able to set the parameter. + bool SetPhysicsParameter(string parm, float value, uint localID); + + // Get parameter. + // Return 'false' if not able to get the parameter. + bool GetPhysicsParameter(string parm, out float value); + + // Get parameter from a particular object + // TODO: + // bool GetPhysicsParameter(string parm, out float value, uint localID); + } +} -- cgit v1.1 From c9e6b7bd10b2cdaa917e41259ae0d612f2171f7a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 19 Aug 2011 00:45:22 +0100 Subject: Stop NPC's getting hypergrid like names in some circumstances. This meant punching in another AddUser() method in IUserManagement to do a direct name to UUID associated without the account check (since NPCs don't have accounts). May address http://opensimulator.org/mantis/view.php?id=5645 --- .../UserManagement/UserManagementModule.cs | 45 +++++++++++++++------- .../Region/Framework/Interfaces/IUserManagement.cs | 37 +++++++++++++++++- OpenSim/Region/Framework/Scenes/Scene.cs | 42 +++++++++++++------- .../World/NPC/Tests/NPCModuleTests.cs | 6 ++- 4 files changed, 101 insertions(+), 29 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index a4861ec..b0b35e4 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -186,7 +186,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } } - private string[] GetUserNames(UUID uuid) { string[] returnstring = new string[2]; @@ -292,6 +291,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return userID.ToString(); } + public void AddUser(UUID uuid, string first, string last) + { + if (m_UserCache.ContainsKey(uuid)) + return; + + UserData user = new UserData(); + user.Id = uuid; + user.FirstName = first; + user.LastName = last; + // user.ProfileURL = we should initialize this to the default + + AddUserInternal(user); + } + + public void AddUser(UUID uuid, string first, string last, string profileURL) + { + AddUser(uuid, profileURL + ";" + first + " " + last); + } + public void AddUser(UUID id, string creatorData) { if (m_UserCache.ContainsKey(id)) @@ -299,18 +317,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData); - UserData user = new UserData(); - user.Id = id; UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id); if (account != null) { - user.FirstName = account.FirstName; - user.LastName = account.LastName; - // user.ProfileURL = we should initialize this to the default + AddUser(id, account.FirstName, account.LastName); } else { + UserData user = new UserData(); + user.Id = id; + if (creatorData != null && creatorData != string.Empty) { //creatorData = ; @@ -338,17 +355,19 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement user.FirstName = "Unknown"; user.LastName = "User"; } - } - lock (m_UserCache) - m_UserCache[id] = user; - - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL); + AddUserInternal(user); + } } - public void AddUser(UUID uuid, string first, string last, string profileURL) + void AddUserInternal(UserData user) { - AddUser(uuid, profileURL + ";" + first + " " + last); + lock (m_UserCache) + m_UserCache[user.Id] = user; + + m_log.DebugFormat( + "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", + user.Id, user.FirstName, user.LastName, user.HomeURL); } //public void AddUser(UUID uuid, string userData) diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs index 5d30aa8..c66e053 100644 --- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs +++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs @@ -5,13 +5,48 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { + /// + /// This maintains the relationship between a UUID and a user name. + /// public interface IUserManagement { string GetUserName(UUID uuid); string GetUserHomeURL(UUID uuid); string GetUserUUI(UUID uuid); string GetUserServerURL(UUID uuid, string serverType); - void AddUser(UUID uuid, string userData); + + /// + /// Add a user. + /// + /// + /// If an account is found for the UUID, then the names in this will be used rather than any information + /// extracted from creatorData. + /// + /// + /// The creator data for this user. + void AddUser(UUID uuid, string creatorData); + + /// + /// Add a user. + /// + /// + /// The UUID is related to the name without any other checks being performed, such as user account presence. + /// + /// + /// + /// + void AddUser(UUID uuid, string firstName, string lastName); + + /// + /// Add a user. + /// + /// + /// The arguments apart from uuid are formed into a creatorData string and processing proceeds as for the + /// AddUser(UUID uuid, string creatorData) method. + /// + /// + /// + /// void AddUser(UUID uuid, string firstName, string lastName, string profileURL); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ae88a87..513c0ea 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2582,12 +2582,13 @@ namespace OpenSim.Region.Framework.Scenes } } - if (GetScenePresence(client.AgentId) != null) + ScenePresence createdSp = GetScenePresence(client.AgentId); + if (createdSp != null) { m_LastLogin = Util.EnvironmentTickCount(); // Cache the user's name - CacheUserName(aCircuit); + CacheUserName(createdSp, aCircuit); EventManager.TriggerOnNewClient(client); if (vialogin) @@ -2595,28 +2596,41 @@ namespace OpenSim.Region.Framework.Scenes } } - private void CacheUserName(AgentCircuitData aCircuit) + /// + /// Cache the user name for later use. + /// + /// + /// + private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit) { IUserManagement uMan = RequestModuleInterface(); if (uMan != null) { - string homeURL = string.Empty; string first = aCircuit.firstname, last = aCircuit.lastname; - if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) - homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); - - if (aCircuit.lastname.StartsWith("@")) + if (sp.PresenceType == PresenceType.Npc) + { + uMan.AddUser(aCircuit.AgentID, first, last); + } + else { - string[] parts = aCircuit.firstname.Split('.'); - if (parts.Length >= 2) + string homeURL = string.Empty; + + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); + + if (aCircuit.lastname.StartsWith("@")) { - first = parts[0]; - last = parts[1]; + string[] parts = aCircuit.firstname.Split('.'); + if (parts.Length >= 2) + { + first = parts[0]; + last = parts[1]; + } } - } - uMan.AddUser(aCircuit.AgentID, first, last, homeURL); + uMan.AddUser(aCircuit.AgentID, first, last, homeURL); + } } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index f8afc5a..78296a4 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -34,6 +34,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Region.CoreModules.Avatar.AvatarFactory; +using OpenSim.Region.CoreModules.Framework.UserManagement; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -57,8 +58,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests config.Configs["NPC"].Set("Enabled", "true"); AvatarFactoryModule afm = new AvatarFactoryModule(); + UserManagementModule umm = new UserManagementModule(); + TestScene scene = SceneHelpers.SetupScene(); - SceneHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); + SceneHelpers.SetupSceneModules(scene, config, afm, umm, new NPCModule()); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); @@ -81,6 +84,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc, Is.Not.Null); Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); + Assert.That(umm.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname))); } [Test] -- cgit v1.1 From bb5b396fc5ac15d7451df407e75c2ca99c0b9dd1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 18 Aug 2011 15:27:03 -0700 Subject: Fix exception when using BasicPhysics --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7778ebc..a0e87d0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1603,7 +1603,6 @@ namespace OpenSim.Region.Framework.Scenes RotationOffset, RigidBody, m_localId); - PhysActor.SetMaterial(Material); } catch { @@ -1615,6 +1614,7 @@ namespace OpenSim.Region.Framework.Scenes { PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info PhysActor.SOPDescription = this.Description; + PhysActor.SetMaterial(Material); DoPhysicsPropertyUpdate(RigidBody, true); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } @@ -4530,11 +4530,11 @@ namespace OpenSim.Region.Framework.Scenes RotationOffset, UsePhysics, m_localId); - PhysActor.SetMaterial(Material); pa = PhysActor; if (pa != null) { + PhysActor.SetMaterial(Material); DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) -- cgit v1.1 From 2787207aa287a60a3c7c06fad66d406180033ae2 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 19 Aug 2011 18:47:21 -0400 Subject: Add llRegionSayTo llRegionSayTo(key target, integer channel, string messasge) Allows messages to be sent region-wide to a particular prim. --- .../Scripting/WorldComm/WorldCommModule.cs | 21 +++++++++++++++++ OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 20 ++++++++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 27 +++++++++++++++++----- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 5 ++++ 5 files changed, 68 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index d647e71..6917b14 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -282,6 +282,27 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } + // wComm.DeliverMessageTo(target, channelID, m_host.Name, m_host.UUID, text); + public void DeliverMessageTo(UUID target, int channel, string name, UUID id, string msg) + { + foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + { + // Dont process if this message is from yourself! + if (li.GetHostID().Equals(id)) + continue; + + SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); + if (sPart == null) + continue; + + if ( li.GetHostID().Equals(target)) + { + QueueMessage(new ListenerInfo(li, name, id, msg)); + return; + } + } + } + protected void QueueMessage(ListenerInfo li) { lock (m_pending.SyncRoot) diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs index 8da99a0..8f200ae 100644 --- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs +++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs @@ -81,6 +81,26 @@ namespace OpenSim.Region.Framework.Interfaces void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg); /// + /// Delivers the message to a specified object in the region. + /// + /// + /// Target. + /// + /// + /// Channel. + /// + /// + /// Name. + /// + /// + /// Identifier. + /// + /// + /// Message. + /// + void DeliverMessageTo(UUID target, int channel, string name, UUID id, string msg); + + /// /// Are there any listen events ready to be dispatched? /// /// boolean indication diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c84afee..25d7ad9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -843,6 +843,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text); } + public void llRegionSayTo(string target, int channel, string msg) + { + if (channel == 0) + { + LSLError("Cannot use llRegionSay() on channel 0"); + return; + } + + if (msg.Length > 1023) + msg = msg.Substring(0, 1023); + + m_host.AddScriptLPS(1); + + UUID TargetID; + UUID.TryParse(target, out TargetID); + + IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); + if (wComm != null) + wComm.DeliverMessageTo(TargetID, channel, m_host.Name, m_host.UUID, msg); + } + public LSL_Integer llListen(int channelID, string name, string ID, string msg) { m_host.AddScriptLPS(1); @@ -10486,12 +10507,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api NotImplemented("llGetUsedMemory"); } - public void llRegionSayTo(LSL_Key target, LSL_Integer channel, LSL_String msg) - { - m_host.AddScriptLPS(1); - NotImplemented("llRegionSayTo"); - } - public void llScriptProfiler(LSL_Integer flags) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 27f9c84..4d7d60d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -271,6 +271,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local); void llRefreshPrimURL(); void llRegionSay(int channelID, string text); + void llRegionSayTo(string target, int channelID, string text); void llReleaseCamera(string avatar); void llReleaseControls(); void llReleaseURL(string url); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 303d75e..96e46fd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1199,6 +1199,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llRegionSay(channelID, text); } + public void llRegionSayTo(string key, int channelID, string text) + { + m_LSL_Functions.llRegionSayTo(key, channelID, text); + } + public void llReleaseCamera(string avatar) { m_LSL_Functions.llReleaseCamera(avatar); -- cgit v1.1 From 5e231acdce7a006a4d88a205044d9862f7d4dda8 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sat, 20 Aug 2011 12:36:35 -0400 Subject: Add avatar and attachments to llRegionSay llRegionSay will now message avatars on chan 0 and will message attachments on the avatar that listen on channels other than 0. This behavior is consistant with the LL implementation as tested on regions in Agni with one exception: this implementation does not include issue: https://jira.secondlife.com/browse/SCR-66? --- .../Scripting/WorldComm/WorldCommModule.cs | 71 ++++++++++++++++++++-- OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 9 +-- 3 files changed, 71 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 6917b14..22352f5 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -282,9 +282,71 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } - // wComm.DeliverMessageTo(target, channelID, m_host.Name, m_host.UUID, text); - public void DeliverMessageTo(UUID target, int channel, string name, UUID id, string msg) - { + /// + /// Delivers the message to. + /// + /// + /// Target. + /// + /// + /// Channel. + /// + /// + /// Name. + /// + /// + /// Identifier. + /// + /// + /// Message. + /// + public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error) + { + error = null; + // Is id an avatar? + ScenePresence sp = m_scene.GetScenePresence(target); + + if (sp != null) + { + // Send message to avatar + if (channel == 0) + { + m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false); + } + + List attachments = sp.Attachments; + // Nothing left to do + if (attachments == null) + return true; + + // Get uuid of attachments + List targets = new List(); + foreach ( SceneObjectGroup sog in attachments ) + { + targets.Add(sog.UUID); + } + // Need to check each attachment + foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + { + if (li.GetHostID().Equals(id)) + continue; + + if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) + continue; + + if ( targets.Contains(li.GetHostID())) + QueueMessage(new ListenerInfo(li, name, id, msg)); + } + return true; + } + + // Need to toss an error here + if (channel == 0) + { + error = "Cannot use llRegionSayTo to message objects on channel 0"; + return false; + } + foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) { // Dont process if this message is from yourself! @@ -298,9 +360,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if ( li.GetHostID().Equals(target)) { QueueMessage(new ListenerInfo(li, name, id, msg)); - return; + break; } } + return true; } protected void QueueMessage(ListenerInfo li) diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs index 8f200ae..dafbf30 100644 --- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs +++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Message. /// - void DeliverMessageTo(UUID target, int channel, string name, UUID id, string msg); + bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error); /// /// Are there any listen events ready to be dispatched? diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 25d7ad9..db45354 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -845,11 +845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRegionSayTo(string target, int channel, string msg) { - if (channel == 0) - { - LSLError("Cannot use llRegionSay() on channel 0"); - return; - } + string error = String.Empty; if (msg.Length > 1023) msg = msg.Substring(0, 1023); @@ -861,7 +857,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - wComm.DeliverMessageTo(TargetID, channel, m_host.Name, m_host.UUID, msg); + if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error)) + LSLError(error); } public LSL_Integer llListen(int channelID, string name, string ID, string msg) -- cgit v1.1 From db91044593fc2592c7abb21034aeea8965febbd7 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Mon, 22 Aug 2011 14:51:43 +0200 Subject: Thanks Neil Canham for fixing bulk inventory updates, no sending BulkInventoryUpdate after accepting inventory items. --- .../Avatar/Inventory/Transfer/InventoryTransferModule.cs | 13 ++++++++++++- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index e3d4969..b4f69e6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -278,7 +278,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer else { if (m_TransferModule != null) - m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); + m_TransferModule.SendInstantMessage(im, delegate(bool success) { + // Send BulkUpdateInventory + IInventoryService invService = scene.InventoryService; + UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip + + InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId); + folder = invService.GetFolder(folder); + + ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID)); + + fromUser.ControllingClient.SendBulkUpdateInventory(folder); + }); } } else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index db45354..ef67a0c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3927,7 +3927,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api GridInstantMessage msg = new GridInstantMessage(World, m_host.UUID, m_host.Name+", an object owned by "+ resolveName(m_host.OwnerID)+",", destId, - (byte)InstantMessageDialog.InventoryOffered, + (byte)InstantMessageDialog.TaskInventoryOffered, false, objName+"\n"+m_host.Name+" is located at "+ World.RegionInfo.RegionName+" "+ m_host.AbsolutePosition.ToString(), -- cgit v1.1 From 7cf4bb5256be8e4b6a585e5128ccfc4b132bee04 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 22 Aug 2011 22:13:07 +0100 Subject: Add ISimulatorFeaturesModule so that other modules can register features in addition to the hardcoded ones. --- .../Linden/Caps/SimulatorFeaturesModule.cs | 122 +++++++++++++++------ .../Interfaces/ISimulatorFeaturesModule.cs | 43 ++++++++ 2 files changed, 129 insertions(+), 36 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 9f78948..b531c1f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -43,21 +43,29 @@ using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.ClientStack.Linden { /// - /// SimulatorFeatures capability. This is required for uploading Mesh. + /// SimulatorFeatures capability. + /// + /// + /// This is required for uploading Mesh. /// Since is accepts an open-ended response, we also send more information /// for viewers that care to interpret it. /// /// NOTE: Part of this code was adapted from the Aurora project, specifically /// the normal part of the response in the capability handler. - /// - /// + /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimulatorFeaturesModule : ISharedRegionModule + public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + /// + /// Simulator features + /// + private OSDMap m_features = new OSDMap(); + private string m_MapImageServerURL = string.Empty; private string m_SearchURL = string.Empty; @@ -66,18 +74,20 @@ namespace OpenSim.Region.ClientStack.Linden public void Initialise(IConfigSource source) { IConfig config = source.Configs["SimulatorFeatures"]; - if (config == null) - return; - - m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty); - if (m_MapImageServerURL != string.Empty) + if (config != null) { - m_MapImageServerURL = m_MapImageServerURL.Trim(); - if (!m_MapImageServerURL.EndsWith("/")) - m_MapImageServerURL = m_MapImageServerURL + "/"; + m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty); + if (m_MapImageServerURL != string.Empty) + { + m_MapImageServerURL = m_MapImageServerURL.Trim(); + if (!m_MapImageServerURL.EndsWith("/")) + m_MapImageServerURL = m_MapImageServerURL + "/"; + } + + m_SearchURL = config.GetString("SearchServerURI", string.Empty); } - m_SearchURL = config.GetString("SearchServerURI", string.Empty); + AddDefaultFeatures(); } public void AddRegion(Scene s) @@ -110,43 +120,83 @@ namespace OpenSim.Region.ClientStack.Linden #endregion + /// + /// Add default features + /// + /// + /// TODO: These should be added from other modules rather than hardcoded. + /// + private void AddDefaultFeatures() + { + lock (m_features) + { + m_features["MeshRezEnabled"] = true; + m_features["MeshUploadEnabled"] = true; + m_features["MeshXferEnabled"] = true; + m_features["PhysicsMaterialsEnabled"] = true; + + OSDMap typesMap = new OSDMap(); + typesMap["convex"] = true; + typesMap["none"] = true; + typesMap["prim"] = true; + m_features["PhysicsShapeTypes"] = typesMap; + + // Extra information for viewers that want to use it + OSDMap gridServicesMap = new OSDMap(); + if (m_MapImageServerURL != string.Empty) + gridServicesMap["map-server-url"] = m_MapImageServerURL; + if (m_SearchURL != string.Empty) + gridServicesMap["search"] = m_SearchURL; + m_features["GridServices"] = gridServicesMap; + } + } + public void RegisterCaps(UUID agentID, Caps caps) { - IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), SimulatorFeatures); + IRequestHandler reqHandler + = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest); + caps.RegisterHandler("SimulatorFeatures", reqHandler); } - private Hashtable SimulatorFeatures(Hashtable mDhttpMethod) + public void AddFeature(string name, OSD value) + { + lock (m_features) + m_features[name] = value; + } + + public bool RemoveFeature(string name) + { + lock (m_features) + return m_features.Remove(name); + } + + public bool TryGetFeature(string name, out OSD value) + { + lock (m_features) + return m_features.TryGetValue(name, out value); + } + + public OSDMap GetFeatures() + { + lock (m_features) + return new OSDMap(m_features); + } + + private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod) { m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); - OSDMap data = new OSDMap(); - data["MeshRezEnabled"] = true; - data["MeshUploadEnabled"] = true; - data["MeshXferEnabled"] = true; - data["PhysicsMaterialsEnabled"] = true; - - OSDMap typesMap = new OSDMap(); - typesMap["convex"] = true; - typesMap["none"] = true; - typesMap["prim"] = true; - data["PhysicsShapeTypes"] = typesMap; - - // Extra information for viewers that want to use it - OSDMap gridServicesMap = new OSDMap(); - if (m_MapImageServerURL != string.Empty) - gridServicesMap["map-server-url"] = m_MapImageServerURL; - if (m_SearchURL != string.Empty) - gridServicesMap["search"] = m_SearchURL; - data["GridServices"] = gridServicesMap; //Send back data Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 200; responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; - responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data); + + lock (m_features) + responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features); + return responsedata; } - } } diff --git a/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs b/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs new file mode 100644 index 0000000..8cef14e --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs @@ -0,0 +1,43 @@ +/* + * 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 OpenMetaverse.StructuredData; + +namespace OpenSim.Region.Framework.Interfaces +{ + /// + /// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability. + /// + public interface ISimulatorFeaturesModule + { + void AddFeature(string name, OSD value); + bool RemoveFeature(string name); + bool TryGetFeature(string name, out OSD value); + OSDMap GetFeatures(); + } +} \ No newline at end of file -- cgit v1.1 From 940a248c3d3227ef8da4bba3034b25ad1f1cb241 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 22 Aug 2011 22:44:49 +0100 Subject: minor: comment out simulator features log line --- OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index b531c1f..7b70790 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -185,7 +185,7 @@ namespace OpenSim.Region.ClientStack.Linden private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod) { - m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); +// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); //Send back data Hashtable responsedata = new Hashtable(); -- cgit v1.1 From 2eaadf2dc0459aa4fc2d7cf7de510213ff31c543 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 22 Aug 2011 23:28:37 +0100 Subject: Add warning log message to say which attachment fails validation in order to pin down problems with "Inconsistent Attachment State" --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 719f2da..53c3b85 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3525,12 +3525,22 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectGroup gobj in m_attachments) { if (gobj == null) + { + m_log.WarnFormat( + "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null", Name); return false; + } if (gobj.IsDeleted) + { + m_log.WarnFormat( + "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted", + gobj.Name, gobj.UUID, Name); return false; + } } } + return true; } -- cgit v1.1 From d328046efbcd7449e0421f72138f48272f514481 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 22 Aug 2011 23:59:48 +0100 Subject: If an attachment fails, then start logging the exception for now, in order to help with the inconsistent state bug. This also refactors AttachmentsModules to stop pointlessly refetching the ScenePresence in various methods. However, more of this is required. --- .../Avatar/Attachments/AttachmentsModule.cs | 135 ++++++++++++--------- .../Framework/Interfaces/IAttachmentsModule.cs | 8 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 3 files changed, 84 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 97a1be6..c96de3a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -105,6 +105,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments try { + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + + if (sp == null) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); + return; + } + // If we can't take it, we can't attach it! SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); if (part == null) @@ -123,7 +132,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments AttachmentPt &= 0x7f; // Calls attach with a Zero position - if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) + if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) { m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); @@ -136,12 +145,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } catch (Exception e) { - m_log.DebugFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}", e); + m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); } } - + public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) { + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + + if (sp == null) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); + return false; + } + + return AttachObject(sp, group, AttachmentPt, silent); + } + + public bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) + { Vector3 attachPos = group.AbsolutePosition; // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -175,32 +198,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.AbsolutePosition = attachPos; // Remove any previous attachments - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); UUID itemID = UUID.Zero; - if (sp != null) + foreach (SceneObjectGroup grp in sp.Attachments) { - foreach (SceneObjectGroup grp in sp.Attachments) + if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { - if (grp.GetAttachmentPoint() == (byte)AttachmentPt) - { - itemID = grp.GetFromItemID(); - break; - } + itemID = grp.GetFromItemID(); + break; } - if (itemID != UUID.Zero) - DetachSingleAttachmentToInv(itemID, remoteClient); } + if (itemID != UUID.Zero) + DetachSingleAttachmentToInv(itemID, sp); + if (group.GetFromItemID() == UUID.Zero) { - m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); + m_scene.attachObjectAssetStore(sp.ControllingClient, group, sp.UUID, out itemID); } else { itemID = group.GetFromItemID(); } - ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group); + ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); AttachToAgent(sp, group, AttachmentPt, attachPos, silent); @@ -229,19 +249,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); + + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + + if (sp == null) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", + remoteClient.Name, remoteClient.AgentId); + return UUID.Zero; + } // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim AttachmentPt &= 0x7f; - SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt); + SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, AttachmentPt); if (updateInventoryStatus) { if (att == null) - ShowDetachInUserInventory(itemID, remoteClient); + ShowDetachInUserInventory(itemID, sp.ControllingClient); else - ShowAttachInUserInventory(att, remoteClient, itemID, AttachmentPt); + ShowAttachInUserInventory(att, sp, itemID, AttachmentPt); } if (null == att) @@ -250,15 +280,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return att.UUID; } - protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( + ScenePresence sp, UUID itemID, uint AttachmentPt) { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) { - SceneObjectGroup objatt = invAccess.RezObject(remoteClient, + SceneObjectGroup objatt = invAccess.RezObject(sp.ControllingClient, itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, remoteClient.AgentId, true); + false, false, sp.UUID, true); // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", @@ -277,10 +307,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This will throw if the attachment fails try { - AttachObject(remoteClient, objatt, AttachmentPt, false); + AttachObject(sp, objatt, AttachmentPt, false); } - catch + catch (Exception e) { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", + objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); + // Make sure the object doesn't stick around and bail m_scene.DeleteSceneObject(objatt, false); return null; @@ -295,13 +329,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments objatt.ResumeScripts(); // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); + m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); } else { m_log.WarnFormat( "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, remoteClient.Name, AttachmentPt); + itemID, sp.Name, AttachmentPt); } return objatt; @@ -314,12 +348,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// Update the user inventory to the attachment of an item /// /// - /// + /// /// /// /// - protected UUID ShowAttachInUserInventory( - SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + private UUID ShowAttachInUserInventory( + SceneObjectGroup att, ScenePresence sp, UUID itemID, uint AttachmentPt) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", @@ -328,16 +362,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!att.IsDeleted) AttachmentPt = att.RootPart.AttachmentPoint; - ScenePresence presence; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) - { - InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); - item = m_scene.InventoryService.GetItem(item); + InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); + item = m_scene.InventoryService.GetItem(item); - bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); - if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - } + bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); return att.UUID; } @@ -345,12 +375,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// Update the user inventory to reflect an attachment /// - /// + /// /// /// /// - protected void ShowAttachInUserInventory( - IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) + private void ShowAttachInUserInventory( + ScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) { // m_log.DebugFormat( // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", @@ -374,16 +404,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } - ScenePresence presence; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) - { - // XXYY!! - InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); - item = m_scene.InventoryService.GetItem(item); - bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); - if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - } + InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); + item = m_scene.InventoryService.GetItem(item); + bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); } public void DetachObject(uint objectLocalID, IClientAPI remoteClient) @@ -407,9 +432,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments bool changed = presence.Appearance.DetachAttachment(itemID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - } - DetachSingleAttachmentToInv(itemID, remoteClient); + DetachSingleAttachmentToInv(itemID, presence); + } } public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) @@ -447,7 +472,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? - protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) + private void DetachSingleAttachmentToInv(UUID itemID, ScenePresence sp) { if (itemID == UUID.Zero) // If this happened, someone made a mistake.... return; @@ -474,7 +499,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (p.Inventory.ContainsScripts()) group.HasGroupChanged = true; - UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); + UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); m_scene.DeleteSceneObject(group, false); return; } diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 4cb3df2..e012885 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -49,11 +49,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Attach an object to an avatar. /// - /// - /// - /// - /// - /// + /// + /// + /// /// /// true if the object was successfully attached, false otherwise bool AttachObject( diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 53c3b85..9f9af45 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3540,7 +3540,7 @@ namespace OpenSim.Region.Framework.Scenes } } } - + return true; } -- cgit v1.1 From 1f3ce48be110ad048784aef22ee8458466d3fe06 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Aug 2011 00:04:38 +0100 Subject: If an object failed to attach due to an exception, then try and detach it from the avatar's list of attachments as well as delete it from the scene. This may help with the "Inconsistent attachment state" errors seen on teleport. See http://opensimulator.org/mantis/view.php?id=5644 and linked reports --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index c96de3a..90092ce 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -316,6 +316,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); // Make sure the object doesn't stick around and bail + sp.RemoveAttachment(objatt); m_scene.DeleteSceneObject(objatt, false); return null; } @@ -433,7 +434,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - DetachSingleAttachmentToInv(itemID, presence); + DetachSingleAttachmentToInv(itemID, presence); } } -- cgit v1.1 From afd5469eec3111fa2de9b4e5e53f1f104a521086 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Aug 2011 00:08:29 +0100 Subject: Remove pointless contains check in ScenePresence.RemoveAttachment() --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9f9af45..9518161 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3509,12 +3509,7 @@ namespace OpenSim.Region.Framework.Scenes public void RemoveAttachment(SceneObjectGroup gobj) { lock (m_attachments) - { - if (m_attachments.Contains(gobj)) - { - m_attachments.Remove(gobj); - } - } + m_attachments.Remove(gobj); } public bool ValidateAttachments() -- cgit v1.1 From ce011d7e446e8f05247fc4ed7e0af5a94afbb074 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 23 Aug 2011 10:52:12 -0700 Subject: Protect a check for default texture entry when setting alpha values. Apparently if all faces have their own textures then the default texture is null --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ef67a0c..24be7d4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1619,9 +1619,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api tex.FaceTextures[i].RGBA = texcolor; } } - texcolor = tex.DefaultTexture.RGBA; - texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); - tex.DefaultTexture.RGBA = texcolor; + + // In some cases, the default texture can be null, eg when every face + // has a unique texture + if (tex.DefaultTexture != null) + { + texcolor = tex.DefaultTexture.RGBA; + texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); + tex.DefaultTexture.RGBA = texcolor; + } + part.UpdateTexture(tex); return; } -- cgit v1.1 From 34aed96a2f67b94dbb4fb1900f8fa1e3228a7d50 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Aug 2011 21:20:23 +0100 Subject: replace old TestAddAttachments() with a more thorough TestAddAttachment() --- .../Attachments/Tests/AttachmentsModuleTests.cs | 35 +++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 5bac4c6..87255aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -60,6 +60,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public AgentCircuitData acd1; public SceneObjectGroup sog1, sog2; + private AttachmentsModule m_attMod; + [SetUp] public void Init() { @@ -71,7 +73,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); scene = SceneHelpers.SetupScene(); - SceneHelpers.SetupSceneModules(scene, config, new AttachmentsModule(), new BasicInventoryAccessModule()); + m_attMod = new AttachmentsModule(); + SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); agent1 = UUID.Random(); random = new Random(); @@ -86,18 +89,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // threads. Possibly, later tests should be rewritten not to worry about such things. Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; } - + [Test] - public void TestAddAttachments() + public void TestAddAttachment() { TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); - ScenePresence presence = SceneHelpers.AddScenePresence(scene, agent1); - presence.AddAttachment(sog1); - presence.AddAttachment(sog2); + UUID userId = TestHelpers.ParseTail(0x1); + UUID attItemId = TestHelpers.ParseTail(0x2); + UUID attAssetId = TestHelpers.ParseTail(0x3); + string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, userId); + ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); + InventoryItemBase attItem + = UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + + m_attMod.RezSingleAttachmentFromInventory( + presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + + // Check status on scene presence Assert.That(presence.HasAttachments(), Is.True); - Assert.That(presence.ValidateAttachments(), Is.True); + List attachments = presence.Attachments; + Assert.That(attachments.Count, Is.EqualTo(1)); + Assert.That(attachments[0].Name, Is.EqualTo(attName)); + Assert.That(attachments[0].GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + + // Check item status + Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] -- cgit v1.1 From 805ba268d5b642b7a9bc8d1ca10ce2e94ae2913a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Aug 2011 21:37:36 +0100 Subject: replace TestRemoveAttachments() with a more thorough TestRemoveAttachment() --- .../Attachments/Tests/AttachmentsModuleTests.cs | 78 ++++++++-------------- 1 file changed, 27 insertions(+), 51 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 87255aa..71321cc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -54,12 +54,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [TestFixture] public class AttachmentsModuleTests { - public Scene scene; - public UUID agent1; - public static Random random; - public AgentCircuitData acd1; - public SceneObjectGroup sog1, sog2; - + private Scene scene; private AttachmentsModule m_attMod; [SetUp] @@ -75,11 +70,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene = SceneHelpers.SetupScene(); m_attMod = new AttachmentsModule(); SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); - - agent1 = UUID.Random(); - random = new Random(); - sog1 = NewSOG(UUID.Random(), scene, agent1); - sog2 = NewSOG(UUID.Random(), scene, agent1); } [TearDown] @@ -122,16 +112,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] - public void TestRemoveAttachments() + public void TestRemoveAttachment() { TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID userId = TestHelpers.ParseTail(0x1); + UUID attItemId = TestHelpers.ParseTail(0x2); + UUID attAssetId = TestHelpers.ParseTail(0x3); + string attName = "att"; + + UserAccountHelpers.CreateUserWithInventory(scene, userId); + ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); + InventoryItemBase attItem + = UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + + m_attMod.RezSingleAttachmentFromInventory( + presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + + // ### + m_attMod.ShowDetachInUserInventory(attItemId, presence.ControllingClient); - ScenePresence presence = SceneHelpers.AddScenePresence(scene, agent1); - presence.AddAttachment(sog1); - presence.AddAttachment(sog2); - presence.RemoveAttachment(sog1); - presence.RemoveAttachment(sog2); + // Check status on scene presence Assert.That(presence.HasAttachments(), Is.False); + List attachments = presence.Attachments; + Assert.That(attachments.Count, Is.EqualTo(0)); + + // Check item status + Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); } [Test] @@ -183,39 +192,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful"); // Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted"); // Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); -// } - - private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent) - { - SceneObjectPart sop = new SceneObjectPart(); - sop.Name = RandomName(); - sop.Description = RandomName(); - sop.Text = RandomName(); - sop.SitName = RandomName(); - sop.TouchName = RandomName(); - sop.UUID = uuid; - sop.Shape = PrimitiveBaseShape.Default; - sop.Shape.State = 1; - sop.OwnerID = agent; - - SceneObjectGroup sog = new SceneObjectGroup(sop); - sog.SetScene(scene); - - return sog; - } - - private static string RandomName() - { - StringBuilder name = new StringBuilder(); - int size = random.Next(5,12); - char ch; - for (int i = 0; i < size; i++) - { - ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ; - name.Append(ch); - } - - return name.ToString(); - } +// } } } \ No newline at end of file -- cgit v1.1 From 014cd4f8bb018391aef8e3301988975403b939a1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Aug 2011 21:41:16 +0100 Subject: remove mono compiler warnings --- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 2 -- .../ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs | 4 ---- .../Authorization/RemoteAuthorizationServiceConnector.cs | 4 ---- .../ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs | 2 +- .../ServiceConnectorsOut/MapImage/MapImageServiceModule.cs | 1 - .../CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs | 2 +- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs | 2 +- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 1 - 9 files changed, 4 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 71321cc..6f242e5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -130,8 +130,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests m_attMod.RezSingleAttachmentFromInventory( presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - - // ### m_attMod.ShowDetachInUserInventory(attItemId, presence.ControllingClient); // Check status on scene presence diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs index b570155..e5af1f4 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs @@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage private static bool m_Enabled = false; private IConfigSource m_Config; - bool m_Registered = false; #region IRegionModule interface @@ -64,9 +63,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled"); new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService"); } - } - } public void PostInitialise() @@ -106,6 +103,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage } #endregion - } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs index 5fa27b8..003324f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs @@ -125,7 +125,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization bool isAuthorized = true; message = String.Empty; - string mail = String.Empty; // get the scene this call is being made for Scene scene = null; @@ -144,9 +143,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization { UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); - if (account != null) - mail = account.Email; - isAuthorized = IsAuthorizedForRegion( userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 0c57618..65e39c0 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs @@ -280,7 +280,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { // m_log.DebugFormat("[LOCAL INVENTORY SERVICES CONNECTOR]: Requesting inventory item {0}", item.ID); - UUID requestedItemId = item.ID; +// UUID requestedItemId = item.ID; item = m_InventoryService.GetItem(item); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index e224670..6d3ace9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -61,7 +61,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage private bool m_enabled = false; private IMapImageService m_MapService; - private string m_serverUrl = String.Empty; private Dictionary m_scenes = new Dictionary(); private int m_refreshtime = 0; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index 59a407f..e2e383f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs @@ -39,7 +39,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence { public class PresenceDetector { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IPresenceService m_PresenceService; private Scene m_aScene; diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 7554e12..2117827 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -743,7 +743,7 @@ namespace OpenSim.Region.CoreModules.World.Land // Corner case. If an autoreturn happens during sim startup // we will come here with the list uninitialized // - int landId = m_landIDList[x, y]; +// int landId = m_landIDList[x, y]; // if (landId == 0) // m_log.DebugFormat( diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index dca842a..efede5c 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land public class PrimCountModule : IPrimCountModule, INonSharedRegionModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_Scene; private Dictionary m_PrimCounts = diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 710230a..857079c 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -435,7 +435,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap List parcels = landChannel.AllParcels(); // Local Map Item Request - int tc = Environment.TickCount; List mapitems = new List(); mapItemReply mapitem = new mapItemReply(); if ((parcels != null) && (parcels.Count >= 1)) -- cgit v1.1 From 97b207240ee79abfec08d2dfaa9385211eb305c8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Aug 2011 22:05:22 +0100 Subject: rename AttachmentsModule.ShowDetachInUserInventory() to DetachSingleAttachmentToInv() for consistency and to reflect it's actual behaviour --- .../Avatar/Attachments/AttachmentsModule.cs | 11 +++++------ .../Attachments/Tests/AttachmentsModuleTests.cs | 2 +- .../Framework/Interfaces/IAttachmentsModule.cs | 22 +++++++--------------- .../Shared/Api/Implementation/LSL_Api.cs | 2 +- 4 files changed, 14 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 90092ce..a854c11 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory; client.OnObjectAttach += AttachObject; client.OnObjectDetach += DetachObject; - client.OnDetachAttachmentIntoInv += ShowDetachInUserInventory; + client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv; } public void UnsubscribeFromClientEvents(IClientAPI client) @@ -89,7 +89,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory; client.OnObjectAttach -= AttachObject; client.OnObjectDetach -= DetachObject; - client.OnDetachAttachmentIntoInv -= ShowDetachInUserInventory; + client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv; } /// @@ -269,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (updateInventoryStatus) { if (att == null) - ShowDetachInUserInventory(itemID, sp.ControllingClient); + DetachSingleAttachmentToInv(itemID, sp.ControllingClient); else ShowAttachInUserInventory(att, sp, itemID, AttachmentPt); } @@ -417,12 +417,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); if (group != null) { - //group.DetachToGround(); - ShowDetachInUserInventory(group.GetFromItemID(), remoteClient); + DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); } } - public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient) + public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) { ScenePresence presence; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 6f242e5..6695a9d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -130,7 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests m_attMod.RezSingleAttachmentFromInventory( presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.ShowDetachInUserInventory(attItemId, presence.ControllingClient); + m_attMod.DetachSingleAttachmentToInv(attItemId, presence.ControllingClient); // Check status on scene presence Assert.That(presence.HasAttachments(), Is.False); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index e012885..0c82411 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Interfaces IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); /// - /// Attach an object to an avatar. + /// Attach an object to an avatar /// /// /// @@ -110,11 +110,11 @@ namespace OpenSim.Region.Framework.Interfaces void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient); /// - /// Update the user inventory to show a detach. + /// Detach the given item so that it remains in the user's inventory. /// /// /param> /// - void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); + void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient); /// /// Update the position of an attachment. @@ -126,18 +126,10 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Update the user inventory with a changed attachment /// - /// - /// A - /// - /// - /// A - /// - /// - /// A - /// - /// - /// A - /// + /// + /// + /// + /// void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 24be7d4..ffa0e24 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3031,7 +3031,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; if (attachmentsModule != null) - attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient); + attachmentsModule.DetachSingleAttachmentToInv(itemID, presence.ControllingClient); } public void llTakeCamera(string avatar) -- cgit v1.1 From cf3ffe5bb4c6a8bea9599b6143c2f7793500c984 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 20:49:23 +0100 Subject: Fix llAttachToAvatar() Apart from one obvious bug, this was failing because attempting to serialize the script from inside the script (as part of saving the attachment as an inventory asset) was triggering an extremely long delay. So we now don't do this. The state will be serialized anyway when the avatar normally logs out. The worst that can happen is that if the client/server crashes, the attachment scripts start without previous state. --- .../Avatar/Attachments/AttachmentsModule.cs | 35 +++++++++++++++------- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 14 +++++++-- .../Scenes/Serialization/SceneObjectSerializer.cs | 31 +++++++++++++------ .../ScriptEngine/Interfaces/IScriptInstance.cs | 11 +++++++ .../Shared/Api/Implementation/LSL_Api.cs | 4 +-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 9 ++++++ 6 files changed, 80 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a854c11..c274a5b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -101,7 +101,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { -// m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", +// objectLocalID, remoteClient.Name, AttachmentPt, silent); try { @@ -163,8 +165,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return AttachObject(sp, group, AttachmentPt, silent); } - public bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) + private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", +// group.Name, group.LocalId, sp.Name, AttachmentPt, silent); + + if (sp.GetAttachments(AttachmentPt).Contains(group)) + { +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, AttachmentPt); + + return false; + } + Vector3 attachPos = group.AbsolutePosition; // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -211,14 +226,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (itemID != UUID.Zero) DetachSingleAttachmentToInv(itemID, sp); - if (group.GetFromItemID() == UUID.Zero) - { + itemID = group.GetFromItemID(); + if (itemID == UUID.Zero) m_scene.attachObjectAssetStore(sp.ControllingClient, group, sp.UUID, out itemID); - } - else - { - itemID = group.GetFromItemID(); - } ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); @@ -548,7 +558,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", grp.UUID, grp.GetAttachmentPoint()); - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); + InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index afc1a4f..94126f0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1873,6 +1873,8 @@ namespace OpenSim.Region.Framework.Scenes public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) { +// m_log.DebugFormat("[SCENE]: Called attachObjectAssetStore for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); + itemID = UUID.Zero; if (grp != null) { @@ -1881,16 +1883,20 @@ namespace OpenSim.Region.Framework.Scenes ? 250 : grp.AbsolutePosition.X) , - (grp.AbsolutePosition.X > (int)Constants.RegionSize) + (grp.AbsolutePosition.Y > (int)Constants.RegionSize) ? 250 - : grp.AbsolutePosition.X, + : grp.AbsolutePosition.Y, grp.AbsolutePosition.Z); Vector3 originalPosition = grp.AbsolutePosition; grp.AbsolutePosition = inventoryStoredPosition; - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); grp.AbsolutePosition = originalPosition; @@ -1900,6 +1906,7 @@ namespace OpenSim.Region.Framework.Scenes (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), remoteClient.AgentId); + AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); @@ -1948,6 +1955,7 @@ namespace OpenSim.Region.Framework.Scenes itemID = item.ID; return item.AssetID; } + return UUID.Zero; } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 8fb9fad..a60ee9b 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -127,26 +127,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject) { + return ToOriginalXmlFormat(sceneObject, true); + } + + /// + /// Serialize a scene object to the original xml format + /// + /// + /// Control whether script states are also serialized. + /// + public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, bool doScriptStates) + { using (StringWriter sw = new StringWriter()) { using (XmlTextWriter writer = new XmlTextWriter(sw)) { - ToOriginalXmlFormat(sceneObject, writer); + ToOriginalXmlFormat(sceneObject, writer, doScriptStates); } return sw.ToString(); } } - /// /// Serialize a scene object to the original xml format /// /// /// - public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) + public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates) { - ToOriginalXmlFormat(sceneObject, writer, false); + ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false); } /// @@ -156,10 +166,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// /// If false, don't write the enclosing SceneObjectGroup element /// - public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool noRootElement) + public static void ToOriginalXmlFormat( + SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates, bool noRootElement) { - //m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); - //int time = System.Environment.TickCount; +// m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", sceneObject.Name); +// int time = System.Environment.TickCount; if (!noRootElement) writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); @@ -182,12 +193,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } writer.WriteEndElement(); // OtherParts - sceneObject.SaveScriptedState(writer); + + if (doScriptStates) + sceneObject.SaveScriptedState(writer); if (!noRootElement) writer.WriteEndElement(); // SceneObjectGroup - //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); +// m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", sceneObject.Name, System.Environment.TickCount - time); } protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 8b7871b..0cc0fe7 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -58,7 +58,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// public interface IScriptInstance { + /// + /// Is this script currently running? + /// bool Running { get; set; } + bool ShuttingDown { get; set; } string State { get; set; } IScriptEngine Engine { get; } @@ -78,7 +82,14 @@ namespace OpenSim.Region.ScriptEngine.Interfaces void Init(); void Start(); + + /// + /// Stop the script. + /// + /// + /// true if the script was successfully stopped, false otherwise bool Stop(int timeout); + void SetState(string state); void PostEvent(EventParams data); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ffa0e24..d340ef2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2964,8 +2964,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) - return; +// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) +// return; TaskInventoryItem item; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d253c6a..c443669 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1294,9 +1294,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine public string GetXMLState(UUID itemID) { +// m_log.DebugFormat("[XEngine]: Getting XML state for {0}", itemID); + IScriptInstance instance = GetInstance(itemID); if (instance == null) + { +// m_log.DebugFormat("[XEngine]: Found no script for {0}, returning empty string", itemID); return ""; + } + string xml = instance.GetXMLState(); XmlDocument sdoc = new XmlDocument(); @@ -1437,6 +1443,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine mapData.InnerText = map; stateData.AppendChild(mapData); + +// m_log.DebugFormat("[XEngine]: Got XML state for {0}", itemID); + return doc.InnerXml; } -- cgit v1.1 From b9ec625dbf99955c983b75651430785217559483 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:07:46 +0100 Subject: add TestAddAttachmentFromGround() regression test --- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- .../Attachments/Tests/AttachmentsModuleTests.cs | 32 +++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index c274a5b..f254974 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -563,7 +563,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // the client/server crashes rather than logging out normally, the attachment's scripts will resume // without state on relog. Arguably, this is what we want anyway. string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); - + InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 6695a9d..b4ff055 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -81,7 +81,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] - public void TestAddAttachment() + public void TestAddAttachmentFromGround() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID userId = TestHelpers.ParseTail(0x1); + string attName = "att"; + + UserAccountHelpers.CreateUserWithInventory(scene, userId); + ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; + + m_attMod.AttachObject(presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); + + SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.UUID); + Assert.That(attSo.IsAttachment); + + // Check status on scene presence + Assert.That(presence.HasAttachments(), Is.True); + List attachments = presence.Attachments; + Assert.That(attachments.Count, Is.EqualTo(1)); + Assert.That(attachments[0].Name, Is.EqualTo(attName)); + Assert.That(attachments[0].GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + + // Check item status + Assert.That(presence.Appearance.GetAttachpoint( + attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest)); + } + + [Test] + public void TestAddAttachmentFromInventory() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); -- cgit v1.1 From ccf07f6ae337acc9c2b8fa30a784ee01ee3de24e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:14:57 +0100 Subject: refactor: remove pointless AgentId argument from attachObjectAssetStore() --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f254974..88fc9e4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -228,7 +228,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments itemID = group.GetFromItemID(); if (itemID == UUID.Zero) - m_scene.attachObjectAssetStore(sp.ControllingClient, group, sp.UUID, out itemID); + m_scene.attachObjectAssetStore(sp.ControllingClient, group, out itemID); ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 94126f0..66905fe 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1871,7 +1871,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) + public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, out UUID itemID) { // m_log.DebugFormat("[SCENE]: Called attachObjectAssetStore for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); -- cgit v1.1 From 0e0d40c810c00dac02d0167866714212351097b0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:18:11 +0100 Subject: minor: remove hardcoded region numbers with the region size constant and a currently hardcoded offset --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 66905fe..3e87578 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1880,11 +1880,11 @@ namespace OpenSim.Region.Framework.Scenes { Vector3 inventoryStoredPosition = new Vector3 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? 250 + ? Constants.RegionSize - 6 : grp.AbsolutePosition.X) , (grp.AbsolutePosition.Y > (int)Constants.RegionSize) - ? 250 + ? Constants.RegionSize - 6 : grp.AbsolutePosition.Y, grp.AbsolutePosition.Z); -- cgit v1.1 From 274e354006a7a8426ebf339c333f1d4994231eed Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:23:10 +0100 Subject: get rid of pointless grp null check in attachObjectAssetStore() --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 142 ++++++++++----------- 1 file changed, 69 insertions(+), 73 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 3e87578..ac73abd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1876,87 +1876,83 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE]: Called attachObjectAssetStore for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); itemID = UUID.Zero; - if (grp != null) - { - Vector3 inventoryStoredPosition = new Vector3 - (((grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.X) - , - (grp.AbsolutePosition.Y > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.Y, - grp.AbsolutePosition.Z); - - Vector3 originalPosition = grp.AbsolutePosition; - - grp.AbsolutePosition = inventoryStoredPosition; - - // If we're being called from a script, then trying to serialize that same script's state will not complete - // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if - // the client/server crashes rather than logging out normally, the attachment's scripts will resume - // without state on relog. Arguably, this is what we want anyway. - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); - - grp.AbsolutePosition = originalPosition; - - AssetBase asset = CreateAsset( - grp.GetPartName(grp.LocalId), - grp.GetPartDescription(grp.LocalId), - (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml), - remoteClient.AgentId); - AssetService.Store(asset); + Vector3 inventoryStoredPosition = new Vector3 + (((grp.AbsolutePosition.X > (int)Constants.RegionSize) + ? Constants.RegionSize - 6 + : grp.AbsolutePosition.X) + , + (grp.AbsolutePosition.Y > (int)Constants.RegionSize) + ? Constants.RegionSize - 6 + : grp.AbsolutePosition.Y, + grp.AbsolutePosition.Z); - InventoryItemBase item = new InventoryItemBase(); - item.CreatorId = grp.RootPart.CreatorID.ToString(); - item.CreatorData = grp.RootPart.CreatorData; - item.Owner = remoteClient.AgentId; - item.ID = UUID.Random(); - item.AssetID = asset.FullID; - item.Description = asset.Description; - item.Name = asset.Name; - item.AssetType = asset.Type; - item.InvType = (int)InventoryType.Object; - - InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object); - if (folder != null) - item.Folder = folder.ID; - else // oopsies - item.Folder = UUID.Zero; + Vector3 originalPosition = grp.AbsolutePosition; - if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions()) - { - item.BasePermissions = grp.RootPart.NextOwnerMask; - item.CurrentPermissions = grp.RootPart.NextOwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; - item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; - } - else - { - item.BasePermissions = grp.RootPart.BaseMask; - item.CurrentPermissions = grp.RootPart.OwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask; - item.GroupPermissions = grp.RootPart.GroupMask; - } - item.CreationDate = Util.UnixTimeSinceEpoch(); + grp.AbsolutePosition = inventoryStoredPosition; - // sets itemID so client can show item as 'attached' in inventory - grp.SetFromItemID(item.ID); + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); - if (AddInventoryItem(item)) - remoteClient.SendInventoryItemCreateUpdate(item, 0); - else - m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); + grp.AbsolutePosition = originalPosition; + + AssetBase asset = CreateAsset( + grp.GetPartName(grp.LocalId), + grp.GetPartDescription(grp.LocalId), + (sbyte)AssetType.Object, + Utils.StringToBytes(sceneObjectXml), + remoteClient.AgentId); + + AssetService.Store(asset); - itemID = item.ID; - return item.AssetID; + InventoryItemBase item = new InventoryItemBase(); + item.CreatorId = grp.RootPart.CreatorID.ToString(); + item.CreatorData = grp.RootPart.CreatorData; + item.Owner = remoteClient.AgentId; + item.ID = UUID.Random(); + item.AssetID = asset.FullID; + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; + item.InvType = (int)InventoryType.Object; + + InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object); + if (folder != null) + item.Folder = folder.ID; + else // oopsies + item.Folder = UUID.Zero; + + if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions()) + { + item.BasePermissions = grp.RootPart.NextOwnerMask; + item.CurrentPermissions = grp.RootPart.NextOwnerMask; + item.NextPermissions = grp.RootPart.NextOwnerMask; + item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; + item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; + } + else + { + item.BasePermissions = grp.RootPart.BaseMask; + item.CurrentPermissions = grp.RootPart.OwnerMask; + item.NextPermissions = grp.RootPart.NextOwnerMask; + item.EveryOnePermissions = grp.RootPart.EveryoneMask; + item.GroupPermissions = grp.RootPart.GroupMask; } + item.CreationDate = Util.UnixTimeSinceEpoch(); - return UUID.Zero; + // sets itemID so client can show item as 'attached' in inventory + grp.SetFromItemID(item.ID); + + if (AddInventoryItem(item)) + remoteClient.SendInventoryItemCreateUpdate(item, 0); + else + m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); + + itemID = item.ID; + return item.AssetID; } /// -- cgit v1.1 From 5eeee480d47b855774829c94aadcb69af8c0e8da Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:35:44 +0100 Subject: refactor: move Scene.Inventory.attachObjectAssetStore() into AttachmentsModule.AddSceneObjectAsAttachment() --- .../Avatar/Attachments/AttachmentsModule.cs | 102 ++++++++++++++++++++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 84 ----------------- 2 files changed, 100 insertions(+), 86 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 88fc9e4..5661254 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -46,7 +46,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected Scene m_scene = null; + private Scene m_scene = null; + private IDialogModule m_dialogModule; public string Name { get { return "Attachments Module"; } } public Type ReplaceableInterface { get { return null; } } @@ -56,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void AddRegion(Scene scene) { m_scene = scene; + m_dialogModule = m_scene.RequestModuleInterface(); m_scene.RegisterModuleInterface(this); m_scene.EventManager.OnNewClient += SubscribeToClientEvents; // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI @@ -228,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments itemID = group.GetFromItemID(); if (itemID == UUID.Zero) - m_scene.attachObjectAssetStore(sp.ControllingClient, group, out itemID); + AddSceneObjectAsAttachment(sp.ControllingClient, group, out itemID); ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); @@ -656,5 +658,101 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // it get cleaned up so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); } + + /// + /// Add a scene object that was previously free in the scene as an attachment to an avatar. + /// + /// + /// + /// + /// + private UUID AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp, out UUID itemID) + { +// m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); + + itemID = UUID.Zero; + + Vector3 inventoryStoredPosition = new Vector3 + (((grp.AbsolutePosition.X > (int)Constants.RegionSize) + ? Constants.RegionSize - 6 + : grp.AbsolutePosition.X) + , + (grp.AbsolutePosition.Y > (int)Constants.RegionSize) + ? Constants.RegionSize - 6 + : grp.AbsolutePosition.Y, + grp.AbsolutePosition.Z); + + Vector3 originalPosition = grp.AbsolutePosition; + + grp.AbsolutePosition = inventoryStoredPosition; + + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); + + grp.AbsolutePosition = originalPosition; + + AssetBase asset = m_scene.CreateAsset( + grp.GetPartName(grp.LocalId), + grp.GetPartDescription(grp.LocalId), + (sbyte)AssetType.Object, + Utils.StringToBytes(sceneObjectXml), + remoteClient.AgentId); + + m_scene.AssetService.Store(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.CreatorId = grp.RootPart.CreatorID.ToString(); + item.CreatorData = grp.RootPart.CreatorData; + item.Owner = remoteClient.AgentId; + item.ID = UUID.Random(); + item.AssetID = asset.FullID; + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; + item.InvType = (int)InventoryType.Object; + + InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object); + if (folder != null) + item.Folder = folder.ID; + else // oopsies + item.Folder = UUID.Zero; + + if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) + { + item.BasePermissions = grp.RootPart.NextOwnerMask; + item.CurrentPermissions = grp.RootPart.NextOwnerMask; + item.NextPermissions = grp.RootPart.NextOwnerMask; + item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; + item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; + } + else + { + item.BasePermissions = grp.RootPart.BaseMask; + item.CurrentPermissions = grp.RootPart.OwnerMask; + item.NextPermissions = grp.RootPart.NextOwnerMask; + item.EveryOnePermissions = grp.RootPart.EveryoneMask; + item.GroupPermissions = grp.RootPart.GroupMask; + } + item.CreationDate = Util.UnixTimeSinceEpoch(); + + // sets itemID so client can show item as 'attached' in inventory + grp.SetFromItemID(item.ID); + + if (m_scene.AddInventoryItem(item)) + { + remoteClient.SendInventoryItemCreateUpdate(item, 0); + } + else + { + if (m_dialogModule != null) + m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); + } + + itemID = item.ID; + return item.AssetID; + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index ac73abd..9358e7b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1871,90 +1871,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, out UUID itemID) - { -// m_log.DebugFormat("[SCENE]: Called attachObjectAssetStore for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); - - itemID = UUID.Zero; - - Vector3 inventoryStoredPosition = new Vector3 - (((grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.X) - , - (grp.AbsolutePosition.Y > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.Y, - grp.AbsolutePosition.Z); - - Vector3 originalPosition = grp.AbsolutePosition; - - grp.AbsolutePosition = inventoryStoredPosition; - - // If we're being called from a script, then trying to serialize that same script's state will not complete - // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if - // the client/server crashes rather than logging out normally, the attachment's scripts will resume - // without state on relog. Arguably, this is what we want anyway. - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); - - grp.AbsolutePosition = originalPosition; - - AssetBase asset = CreateAsset( - grp.GetPartName(grp.LocalId), - grp.GetPartDescription(grp.LocalId), - (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml), - remoteClient.AgentId); - - AssetService.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.CreatorId = grp.RootPart.CreatorID.ToString(); - item.CreatorData = grp.RootPart.CreatorData; - item.Owner = remoteClient.AgentId; - item.ID = UUID.Random(); - item.AssetID = asset.FullID; - item.Description = asset.Description; - item.Name = asset.Name; - item.AssetType = asset.Type; - item.InvType = (int)InventoryType.Object; - - InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object); - if (folder != null) - item.Folder = folder.ID; - else // oopsies - item.Folder = UUID.Zero; - - if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions()) - { - item.BasePermissions = grp.RootPart.NextOwnerMask; - item.CurrentPermissions = grp.RootPart.NextOwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; - item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; - } - else - { - item.BasePermissions = grp.RootPart.BaseMask; - item.CurrentPermissions = grp.RootPart.OwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask; - item.GroupPermissions = grp.RootPart.GroupMask; - } - item.CreationDate = Util.UnixTimeSinceEpoch(); - - // sets itemID so client can show item as 'attached' in inventory - grp.SetFromItemID(item.ID); - - if (AddInventoryItem(item)) - remoteClient.SendInventoryItemCreateUpdate(item, 0); - else - m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); - - itemID = item.ID; - return item.AssetID; - } - /// /// Event Handler Rez an object into a scene /// Calls the non-void event handler -- cgit v1.1 From 801b7f18a7170b3df7f678e927122125f1c16eba Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:40:36 +0100 Subject: return InventoryItemBase from AddSceneObjectAsAttachment() --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 5661254..928d43f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -230,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments itemID = group.GetFromItemID(); if (itemID == UUID.Zero) - AddSceneObjectAsAttachment(sp.ControllingClient, group, out itemID); + itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); @@ -664,14 +664,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - /// - /// - private UUID AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp, out UUID itemID) + /// The user inventory item created that holds the attachment. + private InventoryItemBase AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp) { // m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); - itemID = UUID.Zero; - Vector3 inventoryStoredPosition = new Vector3 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) ? Constants.RegionSize - 6 @@ -751,8 +748,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); } - itemID = item.ID; - return item.AssetID; + return item; } } } -- cgit v1.1 From 9ba4511d3e6b63d51f951519151aaae1c59250d6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 21:53:12 +0100 Subject: add SOG helper properties IsPhantom, IsTemporary, etc. to improve code readability use these in some sog methods --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 66 +++++++++++++++------- 1 file changed, 46 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fe96152..079148f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -167,6 +167,44 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Is this scene object phantom? + /// + /// + /// Updating must currently take place through UpdatePrimFlags() + /// + public bool IsPhantom + { + get { return (RootPart.Flags & PrimFlags.Phantom) != 0; } + } + + /// + /// Does this scene object use physics? + /// + /// + /// Updating must currently take place through UpdatePrimFlags() + /// + public bool UsesPhysics + { + get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; } + } + + /// + /// Is this scene object temporary? + /// + /// + /// Updating must currently take place through UpdatePrimFlags() + /// + public bool IsTemporary + { + get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; } + } + + public bool IsVolumeDetect + { + get { return RootPart.VolumeDetectActive; } + } + public float scriptScore; private Vector3 lastPhysGroupPos; @@ -1510,36 +1548,24 @@ namespace OpenSim.Region.Framework.Scenes SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); } - public void ScriptSetPhysicsStatus(bool UsePhysics) + public void ScriptSetPhysicsStatus(bool usePhysics) { - bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); - bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); - bool IsVolumeDetect = RootPart.VolumeDetectActive; - UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); + UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); } - public void ScriptSetTemporaryStatus(bool TemporaryStatus) + public void ScriptSetTemporaryStatus(bool makeTemporary) { - bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); - bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); - bool IsVolumeDetect = RootPart.VolumeDetectActive; - UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect); + UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect); } - public void ScriptSetPhantomStatus(bool PhantomStatus) + public void ScriptSetPhantomStatus(bool makePhantom) { - bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); - bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); - bool IsVolumeDetect = RootPart.VolumeDetectActive; - UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect); + UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect); } - public void ScriptSetVolumeDetect(bool VDStatus) + public void ScriptSetVolumeDetect(bool makeVolumeDetect) { - bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); - bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); - bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); - UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus); + UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect); /* ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore -- cgit v1.1 From 73d913dad25dc1680f66ed2acc32cc6eb672da6b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 22:12:51 +0100 Subject: Make objects attached from the ground phantom --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 ++ .../Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 928d43f..767908e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -669,6 +669,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { // m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); + grp.UpdatePrimFlags(grp.LocalId, grp.UsesPhysics, grp.IsTemporary, true, grp.IsVolumeDetect); + Vector3 inventoryStoredPosition = new Vector3 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) ? Constants.RegionSize - 6 diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b4ff055..9ea6a16 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -97,6 +97,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.UUID); Assert.That(attSo.IsAttachment); + Assert.That(attSo.IsPhantom); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); // Check status on scene presence Assert.That(presence.HasAttachments(), Is.True); @@ -134,8 +137,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(presence.HasAttachments(), Is.True); List attachments = presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(1)); - Assert.That(attachments[0].Name, Is.EqualTo(attName)); - Assert.That(attachments[0].GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.IsPhantom); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); // Check item status Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); -- cgit v1.1 From 21f1b68fdf62779419bf03c522a502428a55d2d9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 22:25:23 +0100 Subject: extend initial rez regression test to check that attachment is phantom --- .../Attachments/Tests/AttachmentsModuleTests.cs | 23 +++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 9ea6a16..2954933 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -95,18 +95,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests m_attMod.AttachObject(presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); - SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.UUID); - Assert.That(attSo.IsAttachment); - Assert.That(attSo.IsPhantom); - Assert.That(attSo.UsesPhysics, Is.False); - Assert.That(attSo.IsTemporary, Is.False); - // Check status on scene presence Assert.That(presence.HasAttachments(), Is.True); List attachments = presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(1)); - Assert.That(attachments[0].Name, Is.EqualTo(attName)); - Assert.That(attachments[0].GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.IsPhantom); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); // Check item status Assert.That(presence.Appearance.GetAttachpoint( @@ -204,7 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests List attachments = presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(1)); - Assert.That(attachments[0].Name, Is.EqualTo(attName)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.IsPhantom); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); } // I'm commenting this test because scene setup NEEDS InventoryService to -- cgit v1.1 From 6d4432f44009d7f7f3e52c56e8ccc994494ec529 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 22:34:26 +0100 Subject: refactor: simplify EntityBase.IsDeleted property --- OpenSim/Region/Framework/Scenes/EntityBase.cs | 7 +------ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 6 +++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index 6fd38e5..213431a 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs @@ -66,12 +66,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Signals whether this entity was in a scene but has since been removed from it. /// - public bool IsDeleted - { - get { return m_isDeleted; } - set { m_isDeleted = value; } - } - protected bool m_isDeleted; + public bool IsDeleted { get; protected internal set; } protected Vector3 m_pos; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 079148f..8f0fa55 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1832,7 +1832,7 @@ namespace OpenSim.Region.Framework.Scenes // an object has been deleted from a scene before update was processed. // A more fundamental overhaul of the update mechanism is required to eliminate all // the race conditions. - if (m_isDeleted) + if (IsDeleted) return; // Even temporary objects take part in physics (e.g. temp-on-rez bullets) @@ -2142,7 +2142,7 @@ namespace OpenSim.Region.Framework.Scenes } m_scene.UnlinkSceneObject(objectGroup, true); - objectGroup.m_isDeleted = true; + objectGroup.IsDeleted = true; objectGroup.m_parts.Clear(); @@ -3385,7 +3385,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual ISceneObject CloneForNewScene() { SceneObjectGroup sog = Copy(false); - sog.m_isDeleted = false; + sog.IsDeleted = false; return sog; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9518161..def4ecb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3809,7 +3809,7 @@ namespace OpenSim.Region.Framework.Scenes List attachments = m_appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { - if (m_isDeleted) + if (IsDeleted) return; int p = attach.AttachPoint; -- cgit v1.1 From d5dc8133fc05ef682c1caa8dc6b587608de7c384 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 22:37:08 +0100 Subject: remove pointless IsDeleted check on SP.RezAttachments() IsDeleted is never set for an SP, even though it's on EntityBase. It might be an idea to set it in the future --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 --- 1 file changed, 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index def4ecb..fc89473 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3809,9 +3809,6 @@ namespace OpenSim.Region.Framework.Scenes List attachments = m_appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { - if (IsDeleted) - return; - int p = attach.AttachPoint; UUID itemID = attach.ItemID; -- cgit v1.1 From 4b4c5e69e59eb7461ccaa67fd4467e0606ffbe8e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 24 Aug 2011 22:45:51 +0100 Subject: Remove forcing of phantom on ground attached objects - attachments can be both non-phantom and flagged as physical. As per Melanie --- OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | 4 ++-- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 -- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 3 --- 3 files changed, 2 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 7b70790..1dd8938 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -56,8 +56,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 767908e..928d43f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -669,8 +669,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { // m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); - grp.UpdatePrimFlags(grp.LocalId, grp.UsesPhysics, grp.IsTemporary, true, grp.IsVolumeDetect); - Vector3 inventoryStoredPosition = new Vector3 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) ? Constants.RegionSize - 6 diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 2954933..859f6ff 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -103,7 +103,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.Name, Is.EqualTo(attName)); Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); - Assert.That(attSo.IsPhantom); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); @@ -140,7 +139,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.Name, Is.EqualTo(attName)); Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); - Assert.That(attSo.IsPhantom); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); @@ -207,7 +205,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.Name, Is.EqualTo(attName)); Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); - Assert.That(attSo.IsPhantom); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); } -- cgit v1.1 From cf42fcd978601a315ac1eb9599ab169f14fc9a8d Mon Sep 17 00:00:00 2001 From: Micheil Merlin Date: Wed, 24 Aug 2011 20:21:51 -0500 Subject: llSetPrimitiveParams correct prim hollow for cases where limit should be 70%. Signed-off-by: BlueWall --- .../Shared/Api/Implementation/LSL_Api.cs | 87 ++++++++++++---------- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 75 ++++++++++++++++--- 2 files changed, 111 insertions(+), 51 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d340ef2..a690e3b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6608,7 +6608,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Util.SHA1Hash(src).ToLower(); } - protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) + protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) { ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); @@ -6619,7 +6619,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT; } - shapeBlock.ProfileCurve = (byte)holeshape; + shapeBlock.PathCurve = pathcurve; + shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape. + shapeBlock.ProfileCurve += profileshape; // Add in the profile shape. if (cut.x < 0f) { cut.x = 0f; @@ -6651,9 +6653,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { hollow = 0f; } - if (hollow > 0.95) + // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a + // Box or Tube) and the hole shape is a square, hollow is limited to + // a max of 70%. The viewer performs its own check on this value but + // we need to do it here also so llGetPrimitiveParams can have access + // to the correct value. + if (profileshape != (byte)ProfileCurve.Square && + holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE) { - hollow = 0.95f; + if (hollow > 0.70f) + { + hollow = 0.70f; + } + } + // Otherwise, hollow is limited to 95%. + else + { + if (hollow > 0.95f) + { + hollow = 0.95f; + } } shapeBlock.ProfileHollow = (ushort)(50000 * hollow); if (twist.x < -1.0f) @@ -6677,20 +6696,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api shapeBlock.ObjectLocalID = part.LocalId; - // retain pathcurve - shapeBlock.PathCurve = part.Shape.PathCurve; - part.Shape.SculptEntry = false; return shapeBlock; } - protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) + // Prim type box, cylinder and prism. + protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) { ObjectShapePacket.ObjectDataBlock shapeBlock; - shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); - - shapeBlock.ProfileCurve += fudge; + shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); if (taper_b.x < 0f) { @@ -6733,18 +6748,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.UpdateShape(shapeBlock); } - protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) + // Prim type sphere. + protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) { ObjectShapePacket.ObjectDataBlock shapeBlock; - shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); + shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); // profile/path swapped for a sphere shapeBlock.PathBegin = shapeBlock.ProfileBegin; shapeBlock.PathEnd = shapeBlock.ProfileEnd; - shapeBlock.ProfileCurve += fudge; - shapeBlock.PathScaleX = 100; shapeBlock.PathScaleY = 100; @@ -6775,13 +6789,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.UpdateShape(shapeBlock); } - protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) + // Prim type torus, tube and ring. + protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) { ObjectShapePacket.ObjectDataBlock shapeBlock; - shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); - - shapeBlock.ProfileCurve += fudge; + shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); // profile/path swapped for a torrus, tube, ring shapeBlock.PathBegin = shapeBlock.ProfileBegin; @@ -6901,7 +6914,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.UpdateShape(shapeBlock); } - protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) + // Prim type sculpt. + protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) { ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); UUID sculptId; @@ -6914,6 +6928,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (sculptId == UUID.Zero) return; + shapeBlock.PathCurve = pathcurve; shapeBlock.ObjectLocalID = part.LocalId; shapeBlock.PathScaleX = 100; shapeBlock.PathScaleY = 150; @@ -6927,9 +6942,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; } - // retain pathcurve - shapeBlock.PathCurve = part.Shape.PathCurve; - part.Shape.SetSculptProperties((byte)type, sculptId); part.Shape.SculptEntry = true; part.UpdateShape(shapeBlock); @@ -7053,8 +7065,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api taper_b = rules.GetVector3Item(idx++); topshear = rules.GetVector3Item(idx++); - part.Shape.PathCurve = (byte)Extrusion.Straight; - SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 1); + SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, + (byte)ProfileShape.Square, (byte)Extrusion.Straight); break; case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: @@ -7067,9 +7079,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api twist = rules.GetVector3Item(idx++); taper_b = rules.GetVector3Item(idx++); topshear = rules.GetVector3Item(idx++); - part.Shape.ProfileShape = ProfileShape.Circle; - part.Shape.PathCurve = (byte)Extrusion.Straight; - SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 0); + SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, + (byte)ProfileShape.Circle, (byte)Extrusion.Straight); break; case (int)ScriptBaseClass.PRIM_TYPE_PRISM: @@ -7082,8 +7093,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api twist = rules.GetVector3Item(idx++); taper_b = rules.GetVector3Item(idx++); topshear = rules.GetVector3Item(idx++); - part.Shape.PathCurve = (byte)Extrusion.Straight; - SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 3); + SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, + (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight); break; case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: @@ -7095,8 +7106,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api hollow = (float)rules.GetLSLFloatItem(idx++); twist = rules.GetVector3Item(idx++); taper_b = rules.GetVector3Item(idx++); // dimple - part.Shape.PathCurve = (byte)Extrusion.Curve1; - SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, 5); + SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, + (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1); break; case (int)ScriptBaseClass.PRIM_TYPE_TORUS: @@ -7114,9 +7125,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api revolutions = (float)rules.GetLSLFloatItem(idx++); radiusoffset = (float)rules.GetLSLFloatItem(idx++); skew = (float)rules.GetLSLFloatItem(idx++); - part.Shape.PathCurve = (byte)Extrusion.Curve1; SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, - revolutions, radiusoffset, skew, 0); + revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1); break; case (int)ScriptBaseClass.PRIM_TYPE_TUBE: @@ -7134,9 +7144,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api revolutions = (float)rules.GetLSLFloatItem(idx++); radiusoffset = (float)rules.GetLSLFloatItem(idx++); skew = (float)rules.GetLSLFloatItem(idx++); - part.Shape.PathCurve = (byte)Extrusion.Curve1; SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, - revolutions, radiusoffset, skew, 1); + revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1); break; case (int)ScriptBaseClass.PRIM_TYPE_RING: @@ -7154,9 +7163,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api revolutions = (float)rules.GetLSLFloatItem(idx++); radiusoffset = (float)rules.GetLSLFloatItem(idx++); skew = (float)rules.GetLSLFloatItem(idx++); - part.Shape.PathCurve = (byte)Extrusion.Curve1; SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, - revolutions, radiusoffset, skew, 3); + revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1); break; case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: @@ -7165,8 +7173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string map = rules.Data[idx++].ToString(); face = (int)rules.GetLSLIntegerItem(idx++); // type - part.Shape.PathCurve = (byte)Extrusion.Curve1; - SetPrimitiveShapeParams(part, map, face); + SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1); break; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 623c82d..8cd1e84 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -182,6 +182,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Vector3.Zero) { Name = obj1Name, UUID = objUuid }; Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True); + // Note that prim hollow check is passed with the other prim params in order to allow the + // specification of a different check value from the prim param. A cylinder, prism, sphere, + // torus or ring, with a hole shape of square, is limited to a hollow of 70%. Test 5 below + // specifies a value of 95% and checks to see if 70% was properly returned. + // Test a sphere. CheckllSetPrimitiveParams( "test 1", // Prim test identification string @@ -191,7 +196,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut 0.80d, // Prim hollow new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist - new LSL_Types.Vector3(0.32d, 0.76d, 0.0d)); // Prim dimple + new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple + 0.80d); // Prim hollow check // Test a prism. CheckllSetPrimitiveParams( @@ -203,7 +209,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests 0.90d, // Prim hollow new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper - new LSL_Types.Vector3(0.0d, 0.0d, 0.0d)); // Prim shear + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear + 0.90d); // Prim hollow check // Test a box. CheckllSetPrimitiveParams( @@ -212,10 +219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScriptBaseClass.PRIM_TYPE_BOX, // Prim type ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut - 0.90d, // Prim hollow + 0.95d, // Prim hollow new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper - new LSL_Types.Vector3(0.0d, 0.0d, 0.0d)); // Prim shear + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear + 0.95d); // Prim hollow check // Test a tube. CheckllSetPrimitiveParams( @@ -232,13 +240,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper 1.0d, // Prim revolutions 1.0d, // Prim radius - 0.0d); // Prim skew + 0.0d, // Prim skew + 0.00d); // Prim hollow check + + // Test a prism. + CheckllSetPrimitiveParams( + "test 5", // Prim test identification string + new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size + ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type + ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type + new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut + 0.95d, // Prim hollow + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist + new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper + new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear + 0.70d); // Prim hollow check + + // Test a sculpted prim. + CheckllSetPrimitiveParams( + "test 6", // Prim test identification string + new LSL_Types.Vector3(2.0d, 2.0d, 2.0d), // Prim size + ScriptBaseClass.PRIM_TYPE_SCULPT, // Prim type + "be293869-d0d9-0a69-5989-ad27f1946fd4", // Prim map + ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE); // Prim sculpt type } // Set prim params for a box, cylinder or prism and check results. public void CheckllSetPrimitiveParams(string primTest, LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, - double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear) + double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear, + double primHollowCheck) { // Set the prim params. m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, @@ -256,7 +287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2), "TestllSetPrimitiveParams " + primTest + " prim hole default check fail"); CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut"); - Assert.AreEqual(primHollow, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, + Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, "TestllSetPrimitiveParams " + primTest + " prim hollow check fail"); CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist"); CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 6), primTest + " prim taper"); @@ -266,7 +297,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // Set prim params for a sphere and check results. public void CheckllSetPrimitiveParams(string primTest, LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, - double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple) + double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, double primHollowCheck) { // Set the prim params. m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, @@ -284,7 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2), "TestllSetPrimitiveParams " + primTest + " prim hole default check fail"); CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut"); - Assert.AreEqual(primHollow, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, + Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, "TestllSetPrimitiveParams " + primTest + " prim hollow check fail"); CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist"); CheckllSetPrimitiveParamsVector(primDimple, m_lslApi.llList2Vector(primParams, 6), primTest + " prim dimple"); @@ -295,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize, LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper, - double primRev, double primRadius, double primSkew) + double primRev, double primRadius, double primSkew, double primHollowCheck) { // Set the prim params. m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, @@ -314,7 +345,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2), "TestllSetPrimitiveParams " + primTest + " prim hole default check fail"); CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut"); - Assert.AreEqual(primHollow, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, + Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY, "TestllSetPrimitiveParams " + primTest + " prim hollow check fail"); CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist"); CheckllSetPrimitiveParamsVector(primHoleSize, m_lslApi.llList2Vector(primParams, 6), primTest + " prim hole size"); @@ -329,6 +360,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests "TestllSetPrimitiveParams " + primTest + " prim skew fail"); } + // Set prim params for a sculpted prim and check results. + public void CheckllSetPrimitiveParams(string primTest, + LSL_Types.Vector3 primSize, int primType, string primMap, int primSculptType) + { + // Set the prim params. + m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, + ScriptBaseClass.PRIM_TYPE, primType, primMap, primSculptType)); + + // Get params for prim to validate settings. + LSL_Types.list primParams = + m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE)); + + // Validate settings. + CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size"); + Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1), + "TestllSetPrimitiveParams " + primTest + " prim type check fail"); + Assert.AreEqual(primMap, (string)m_lslApi.llList2String(primParams, 2), + "TestllSetPrimitiveParams " + primTest + " prim map check fail"); + Assert.AreEqual(primSculptType, m_lslApi.llList2Integer(primParams, 3), + "TestllSetPrimitiveParams " + primTest + " prim type scuplt check fail"); + } + public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg) { // Check each vector component against expected result. -- cgit v1.1 From 6c692d2e2108eac31624b34e462b8b57b5141970 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 21:26:29 +0100 Subject: Fix a very recent regression from llAttachToAvatar() fix where I accidentally stopped normal script state persistence on login/logout and attach/detach --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 928d43f..afaf5c1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -560,11 +560,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", grp.UUID, grp.GetAttachmentPoint()); - // If we're being called from a script, then trying to serialize that same script's state will not complete - // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if - // the client/server crashes rather than logging out normally, the attachment's scripts will resume - // without state on relog. Arguably, this is what we want anyway. - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); -- cgit v1.1 From fcbed6479af5d64383c4ad5578ea28d7db5c3ae2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 21:46:12 +0100 Subject: Downgrade warning about not saving unchanged attachment to debug instead, and change text to better indicate what it's saying --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index afaf5c1..2c49ba8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -552,7 +552,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { if (!grp.HasGroupChanged) { - m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", + grp.UUID, grp.GetAttachmentPoint()); + return; } -- cgit v1.1 From 002313bf132e7eca3d33fdd0c695152146d469b4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 22:02:23 +0100 Subject: refactor: move sog.DetachToInventoryPrep() into AttachmentsModule.DetachSingleAttachmentToInv() --- .../Avatar/Attachments/AttachmentsModule.cs | 25 ++++++++++++----- .../Attachments/Tests/AttachmentsModuleTests.cs | 2 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 32 +++------------------- 3 files changed, 23 insertions(+), 36 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2c49ba8..732e3e3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -502,17 +502,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); - group.DetachToInventoryPrep(); -// m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); + sp.RemoveAttachment(group); - // If an item contains scripts, it's always changed. - // This ensures script state is saved on detach - foreach (SceneObjectPart p in group.Parts) - if (p.Inventory.ContainsScripts()) - group.HasGroupChanged = true; + // Prepare sog for storage + group.ForEachPart( + delegate(SceneObjectPart part) + { + part.AttachedAvatar = UUID.Zero; + + // If there are any scripts, + // then always trigger a new object and state persistence in UpdateKnownItem() + if (part.Inventory.ContainsScripts()) + group.HasGroupChanged = true; + } + ); + + group.RootPart.SetParentLocalId(0); + group.RootPart.IsAttachment = false; + group.AbsolutePosition = group.RootPart.AttachedPos; UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); m_scene.DeleteSceneObject(group, false); + return; } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 859f6ff..afcf05a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] - public void TestRemoveAttachment() + public void TestDetachAttachmentToInventory() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8f0fa55..00e3363 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -147,15 +147,16 @@ namespace OpenSim.Region.Framework.Scenes return false; } - /// + /// /// Is this scene object acting as an attachment? - /// + /// + /// /// We return false if the group has already been deleted. /// /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I /// presume either all or no parts in a linkset can be part of an attachment (in which /// case the value would get proprogated down into all the descendent parts). - /// + /// public bool IsAttachment { get @@ -1017,31 +1018,6 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.ClearUndoState(); } - public void DetachToInventoryPrep() - { - ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); - //Vector3 detachedpos = new Vector3(127f, 127f, 127f); - if (avatar != null) - { - //detachedpos = avatar.AbsolutePosition; - avatar.RemoveAttachment(this); - } - - m_rootPart.AttachedAvatar = UUID.Zero; - - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].AttachedAvatar = UUID.Zero; - - m_rootPart.SetParentLocalId(0); - //m_rootPart.SetAttachmentPoint((byte)0); - m_rootPart.IsAttachment = false; - AbsolutePosition = m_rootPart.AttachedPos; - //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim); - //AttachToBackup(); - //m_rootPart.ScheduleFullUpdate(); - } - /// /// /// -- cgit v1.1 From 1dba047e4d4be6213cfade45630f2b906a5a5755 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 22:17:05 +0100 Subject: add regression test for detaching an attachment to the scene --- .../Attachments/Tests/AttachmentsModuleTests.cs | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index afcf05a..afa61bc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -147,6 +147,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] + public void TestDetachAttachmentToScene() + { + TestHelpers.InMethod(); + log4net.Config.XmlConfigurator.Configure(); + + UUID userId = TestHelpers.ParseTail(0x1); + UUID attItemId = TestHelpers.ParseTail(0x2); + UUID attAssetId = TestHelpers.ParseTail(0x3); + string attName = "att"; + + UserAccountHelpers.CreateUserWithInventory(scene, userId); + ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); + InventoryItemBase attItem + = UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + + UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( + presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToGround(attSoId, presence.ControllingClient); + + // Check status on scene presence + Assert.That(presence.HasAttachments(), Is.False); + List attachments = presence.Attachments; + Assert.That(attachments.Count, Is.EqualTo(0)); + + // Check item status + Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null); + + // Check object in scene + Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); + } + + [Test] public void TestDetachAttachmentToInventory() { TestHelpers.InMethod(); -- cgit v1.1 From dc61bf4b1f96323f1392c1b52e0c034f4945825d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 22:17:27 +0100 Subject: comment out verbose test logging from last commit --- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index afa61bc..072148c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -150,7 +150,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public void TestDetachAttachmentToScene() { TestHelpers.InMethod(); - log4net.Config.XmlConfigurator.Configure(); +// log4net.Config.XmlConfigurator.Configure(); UUID userId = TestHelpers.ParseTail(0x1); UUID attItemId = TestHelpers.ParseTail(0x2); -- cgit v1.1 From 040ad11e611729be16e61dbc5075eca14067c6a9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 22:24:51 +0100 Subject: refactor: remove common presence set up in attachments tests --- .../Attachments/Tests/AttachmentsModuleTests.cs | 70 ++++++++++++---------- 1 file changed, 38 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 072148c..b7d21fd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { private Scene scene; private AttachmentsModule m_attMod; + private ScenePresence m_presence; [SetUp] public void Init() @@ -80,24 +81,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; } + /// + /// Add the standard presence for a test. + /// + private void AddPresence() + { + UUID userId = TestHelpers.ParseTail(0x1); + UserAccountHelpers.CreateUserWithInventory(scene, userId); + m_presence = SceneHelpers.AddScenePresence(scene, userId); + } + [Test] public void TestAddAttachmentFromGround() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); + AddPresence(); string attName = "att"; - UserAccountHelpers.CreateUserWithInventory(scene, userId); - ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; - m_attMod.AttachObject(presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); + m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); // Check status on scene presence - Assert.That(presence.HasAttachments(), Is.True); - List attachments = presence.Attachments; + Assert.That(m_presence.HasAttachments(), Is.True); + List attachments = m_presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); @@ -107,7 +116,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.IsTemporary, Is.False); // Check item status - Assert.That(presence.Appearance.GetAttachpoint( + Assert.That(m_presence.Appearance.GetAttachpoint( attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest)); } @@ -117,23 +126,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); + AddPresence(); + UUID attItemId = TestHelpers.ParseTail(0x2); UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - UserAccountHelpers.CreateUserWithInventory(scene, userId); - ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); InventoryItemBase attItem = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( - presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); // Check status on scene presence - Assert.That(presence.HasAttachments(), Is.True); - List attachments = presence.Attachments; + Assert.That(m_presence.HasAttachments(), Is.True); + List attachments = m_presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); @@ -143,7 +151,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.IsTemporary, Is.False); // Check item status - Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] @@ -152,24 +160,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); + AddPresence(); + UUID attItemId = TestHelpers.ParseTail(0x2); UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - UserAccountHelpers.CreateUserWithInventory(scene, userId); - ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); InventoryItemBase attItem = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( - presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToGround(attSoId, presence.ControllingClient); + m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToGround(attSoId, m_presence.ControllingClient); // Check status on scene presence - Assert.That(presence.HasAttachments(), Is.False); - List attachments = presence.Attachments; + Assert.That(m_presence.HasAttachments(), Is.False); + List attachments = m_presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(0)); // Check item status @@ -185,28 +192,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); + AddPresence(); + UUID attItemId = TestHelpers.ParseTail(0x2); UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - UserAccountHelpers.CreateUserWithInventory(scene, userId); - ScenePresence presence = SceneHelpers.AddScenePresence(scene, userId); InventoryItemBase attItem = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( - presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToInv(attItemId, presence.ControllingClient); + m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); // Check status on scene presence - Assert.That(presence.HasAttachments(), Is.False); - List attachments = presence.Attachments; + Assert.That(m_presence.HasAttachments(), Is.False); + List attachments = m_presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(0)); // Check item status - Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); + Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); } [Test] -- cgit v1.1 From ae614c1264a2c4d06f019f2a91ad481cc2f96770 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 22:37:53 +0100 Subject: refactor: simplify DetachSingleAttachmentToGround() by retrieving the scene object group direct --- .../Avatar/Attachments/AttachmentsModule.cs | 19 ++++++++++--------- .../Region/Framework/Interfaces/IAttachmentsModule.cs | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 732e3e3..42a18c5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -449,29 +449,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) + public void DetachSingleAttachmentToGround(UUID sceneObjectID, IClientAPI remoteClient) { - SceneObjectPart part = m_scene.GetSceneObjectPart(itemID); - if (part == null || part.ParentGroup == null) + SceneObjectGroup so = m_scene.GetSceneObjectGroup(sceneObjectID); + + if (so == null) return; - if (part.ParentGroup.RootPart.AttachedAvatar != remoteClient.AgentId) + if (so.RootPart.AttachedAvatar != remoteClient.AgentId) return; - UUID inventoryID = part.ParentGroup.GetFromItemID(); + UUID inventoryID = so.GetFromItemID(); ScenePresence presence; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { if (!m_scene.Permissions.CanRezObject( - part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) + so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) return; - bool changed = presence.Appearance.DetachAttachment(itemID); + bool changed = presence.Appearance.DetachAttachment(sceneObjectID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - part.ParentGroup.DetachToGround(); + so.DetachToGround(); List uuids = new List(); uuids.Add(inventoryID); @@ -479,7 +480,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments remoteClient.SendRemoveInventoryItem(inventoryID); } - m_scene.EventManager.TriggerOnAttach(part.ParentGroup.LocalId, itemID, UUID.Zero); + m_scene.EventManager.TriggerOnAttach(so.LocalId, sceneObjectID, UUID.Zero); } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 0c82411..86f5a0f 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -105,9 +105,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Detach the given item to the ground. /// - /// + /// /// - void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient); + void DetachSingleAttachmentToGround(UUID sceneObjectID, IClientAPI remoteClient); /// /// Detach the given item so that it remains in the user's inventory. -- cgit v1.1 From 5f3ffc195f60ac54492ccb389843f292b0be7511 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 22:49:11 +0100 Subject: refactor: move SOG.DetachToGround() to AttachmentsModule.DetachSceneObjectToGround() and remove redundant code --- .../Avatar/Attachments/AttachmentsModule.cs | 30 +++++++++++++- .../Region/Framework/Scenes/SceneObjectGroup.cs | 46 +++------------------- 2 files changed, 35 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 42a18c5..93920b0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -472,7 +472,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - so.DetachToGround(); + presence.RemoveAttachment(so); + DetachSceneObjectToGround(so, presence); List uuids = new List(); uuids.Add(inventoryID); @@ -482,6 +483,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(so.LocalId, sceneObjectID, UUID.Zero); } + + /// + /// Detach the given scene objet to the ground. + /// + /// + /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc. + /// + /// The scene object to detach. + /// The scene presence from which the scene object is being detached. + private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp) + { + SceneObjectPart rootPart = so.RootPart; + + rootPart.FromItemID = UUID.Zero; + so.AbsolutePosition = sp.AbsolutePosition; + so.ForEachPart(part => part.AttachedAvatar = UUID.Zero); + rootPart.SetParentLocalId(0); + so.ClearPartAttachmentData(); + rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); + so.HasGroupChanged = true; + rootPart.Rezzed = DateTime.Now; + rootPart.RemFlag(PrimFlags.TemporaryOnRez); + so.AttachToBackup(); + m_scene.EventManager.TriggerParcelPrimCountTainted(); + rootPart.ScheduleFullUpdate(); + rootPart.ClearUndoState(); + } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 00e3363..e3b8fc8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -979,43 +979,16 @@ namespace OpenSim.Region.Framework.Scenes return m_rootPart.Shape.State; } - public void ClearPartAttachmentData() - { - SetAttachmentPoint((Byte)0); - } - - public void DetachToGround() + public void SetAttachmentPoint(byte point) { - ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); - if (avatar == null) - return; - - avatar.RemoveAttachment(this); - - Vector3 detachedpos = new Vector3(127f,127f,127f); - if (avatar == null) - return; - - detachedpos = avatar.AbsolutePosition; - RootPart.FromItemID = UUID.Zero; - - AbsolutePosition = detachedpos; - m_rootPart.AttachedAvatar = UUID.Zero; - SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) - parts[i].AttachedAvatar = UUID.Zero; + parts[i].SetAttachmentPoint(point); + } - m_rootPart.SetParentLocalId(0); - SetAttachmentPoint((byte)0); - m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_scene.m_physicalPrim); - HasGroupChanged = true; - RootPart.Rezzed = DateTime.Now; - RootPart.RemFlag(PrimFlags.TemporaryOnRez); - AttachToBackup(); - m_scene.EventManager.TriggerParcelPrimCountTainted(); - m_rootPart.ScheduleFullUpdate(); - m_rootPart.ClearUndoState(); + public void ClearPartAttachmentData() + { + SetAttachmentPoint((Byte)0); } /// @@ -3349,13 +3322,6 @@ namespace OpenSim.Region.Framework.Scenes return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); } - public void SetAttachmentPoint(byte point) - { - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].SetAttachmentPoint(point); - } - #region ISceneObject public virtual ISceneObject CloneForNewScene() -- cgit v1.1 From 15a514fcbc8f7447fc3a5997b6bbc2fe35974c9a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Aug 2011 23:06:41 +0100 Subject: refactor: simplify SOP.AttachedAvatar into SOG.AttachedAvatar This does a tiny bit to reduce code complexity, memory requirement and the cpu time of pointlessly setting this field to the same value in every SOP --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 15 +++++---------- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 7 +++---- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 12 ++++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 +---- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 ++++---- .../Shared/Api/Implementation/Plugins/SensorRepeat.cs | 4 ++-- .../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- 7 files changed, 26 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 93920b0..3e1cb02 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -456,7 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (so == null) return; - if (so.RootPart.AttachedAvatar != remoteClient.AgentId) + if (so.AttachedAvatar != remoteClient.AgentId) return; UUID inventoryID = so.GetFromItemID(); @@ -498,7 +498,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments rootPart.FromItemID = UUID.Zero; so.AbsolutePosition = sp.AbsolutePosition; - so.ForEachPart(part => part.AttachedAvatar = UUID.Zero); + so.AttachedAvatar = UUID.Zero; rootPart.SetParentLocalId(0); so.ClearPartAttachmentData(); rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); @@ -534,11 +534,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sp.RemoveAttachment(group); // Prepare sog for storage + group.AttachedAvatar = UUID.Zero; + group.ForEachPart( delegate(SceneObjectPart part) { - part.AttachedAvatar = UUID.Zero; - // If there are any scripts, // then always trigger a new object and state persistence in UpdateKnownItem() if (part.Inventory.ContainsScripts()) @@ -656,12 +656,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.DeleteFromStorage(so.UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); - so.RootPart.AttachedAvatar = avatar.UUID; - - //Anakin Lohner bug #3839 - SceneObjectPart[] parts = so.Parts; - for (int i = 0; i < parts.Length; i++) - parts[i].AttachedAvatar = avatar.UUID; + so.AttachedAvatar = avatar.UUID; if (so.RootPart.PhysActor != null) { diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 4595a29..2a76755 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -116,14 +116,13 @@ namespace OpenSim.Region.Framework.Scenes return priority; } - private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) { // And anything attached to this avatar gets top priority as well if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) + if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -136,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) + if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -149,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) + if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index e3b8fc8..fada688 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -169,6 +169,14 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// The avatar to which this scene object is attached. + /// + /// + /// If we're not attached to an avatar then this is UUID.Zero + /// + public UUID AttachedAvatar { get; set; } + + /// /// Is this scene object phantom? /// /// @@ -1540,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes { if (IsAttachment) { - ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); + ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); if (avatar != null) { avatar.PushForce(impulse); @@ -1622,7 +1630,7 @@ namespace OpenSim.Region.Framework.Scenes { if (IsAttachment) { - ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); + ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); if (avatar != null) { avatar.MoveToTarget(target, false); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a0e87d0..e510611 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -221,9 +221,6 @@ namespace OpenSim.Region.Framework.Scenes public scriptEvents AggregateScriptEvents; - public UUID AttachedAvatar; - - public Vector3 AttachedPos; @@ -728,7 +725,7 @@ namespace OpenSim.Region.Framework.Scenes if (IsAttachment) { - ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); + ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); if (sp != null) return sp.AbsolutePosition; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a690e3b..81f1f38 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2099,7 +2099,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (part.ParentGroup.RootPart.AttachmentPoint != 0) { - ScenePresence avatar = World.GetScenePresence(part.AttachedAvatar); + ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar); if (avatar != null) { if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) @@ -2243,7 +2243,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.IsAttachment) { - ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.AttachedAvatar); + ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); vel = avatar.Velocity; } else @@ -3388,7 +3388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.RootPart.AttachedAvatar) + if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) { // When attached, certain permissions are implicit if requested from owner int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | @@ -7460,7 +7460,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Quaternion q; if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) { - ScenePresence avatar = World.GetScenePresence(m_host.AttachedAvatar); + ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); if (avatar != null) if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) q = avatar.CameraRotation; // Mouselook diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index e53a61a..bf74760 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -308,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if // in mouselook. - ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); + ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); q = avatar.Rotation; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); @@ -428,7 +428,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if // in mouselook. - ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); + ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); q = avatar.Rotation; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 783791f..ef9b2ac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -233,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_MaxScriptQueue = maxScriptQueue; m_stateSource = stateSource; m_postOnRez = postOnRez; - m_AttachedAvatar = part.AttachedAvatar; + m_AttachedAvatar = part.ParentGroup.AttachedAvatar; m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; if (part != null) -- cgit v1.1 From 21708b832b1d6679d5f6de27eb3bd0b920ef0fa7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Aug 2011 15:51:21 -0700 Subject: BulletSim: add mesh representation. Use meshes for static objects and switch to hulls for physical objects. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 306 +++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 20 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 31 ++- 3 files changed, 228 insertions(+), 129 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index cc414e9..d1fb576 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -45,6 +45,7 @@ public sealed class BSPrim : PhysicsActor private IMesh _mesh; private PrimitiveBaseShape _pbs; private ShapeData.PhysicsShapeType _shapeType; + private ulong _meshKey; private ulong _hullKey; private List _hulls; @@ -117,6 +118,7 @@ public sealed class BSPrim : PhysicsActor _rotationalVelocity = OMV.Vector3.Zero; _angularVelocity = OMV.Vector3.Zero; _hullKey = 0; + _meshKey = 0; _pbs = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; @@ -147,6 +149,7 @@ public sealed class BSPrim : PhysicsActor _scene.RemoveVehiclePrim(this); // just to make sure _scene.TaintedObject(delegate() { + // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. BulletSimAPI.DestroyObject(_scene.WorldID, _localID); }); } @@ -283,11 +286,6 @@ public sealed class BSPrim : PhysicsActor set { _parentPrim = value; } } - public ulong HullKey - { - get { return _hullKey; } - } - // return true if we are the root of a linkset (there are children to manage) public bool IsRootOfLinkset { @@ -463,7 +461,18 @@ public sealed class BSPrim : PhysicsActor private void SetObjectDynamic() { // non-physical things work best with a mass of zero - _mass = IsStatic ? 0f : CalculateMass(); + if (IsStatic) + { + _mass = 0f; + } + else + { + _mass = CalculateMass(); + // If it's dynamic, make sure the hull has been created for it + // This shouldn't do much work if the object had previously been built + RecreateGeomAndObject(); + + } BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}, mass={4}", LogHeader, _localID, IsStatic, IsSolid, _mass); } @@ -896,26 +905,19 @@ public sealed class BSPrim : PhysicsActor #endregion Mass Calculation // Create the geometry information in Bullet for later use + // The objects needs a hull if it's physical otherwise a mesh is enough // No locking here because this is done when we know physics is not simulating - private void CreateGeom() + // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used + private void CreateGeom(bool forceRebuild) { - // Since we're recreating new, get rid of any previously generated shape - if (_hullKey != 0) + // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. + if (!_scene.NeedsMeshing(_pbs)) { - // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); - BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); - _hullKey = 0; - _hulls.Clear(); - } - - if (_mesh == null) - { - // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) { if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) { - // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to sphere of size {1}", LogHeader, _size); + // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; // Bullet native objects are scaled by the Bullet engine so pass the size in _scale = _size; @@ -923,99 +925,190 @@ public sealed class BSPrim : PhysicsActor } else { - // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); + // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _scale = _size; } } else { - int[] indices = _mesh.getIndexListAsInt(); - List vertices = _mesh.getVertexList(); - - //format conversion from IMesh format to DecompDesc format - List convIndices = new List(); - List convVertices = new List(); - for (int ii = 0; ii < indices.GetLength(0); ii++) + if (IsPhysical) { - convIndices.Add(indices[ii]); + if (forceRebuild || _hullKey == 0) + { + // physical objects require a hull for interaction. + // This will create the mesh if it doesn't already exist + CreateGeomHull(); + } } - foreach (OMV.Vector3 vv in vertices) + else { - convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); + if (forceRebuild || _meshKey == 0) + { + // Static (non-physical) objects only need a mesh for bumping into + CreateGeomMesh(); + } } + } + } + + // No locking here because this is done when we know physics is not simulating + private void CreateGeomMesh() + { + ulong newMeshKey = (ulong)_pbs.GetHashCode(); + + // if this new shape is the same as last time, don't recreate the mesh + if (_meshKey == newMeshKey) return; + + // Since we're recreating new, get rid of any previously generated shape + if (_meshKey != 0) + { + // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _meshKey); + BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); + _mesh = null; + _meshKey = 0; + } + + _meshKey = newMeshKey; + int lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; + // always pass false for physicalness as this creates some sort of bounding box which we don't need + _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, lod, false); + + int[] indices = _mesh.getIndexListAsInt(); + List vertices = _mesh.getVertexList(); + + float[] verticesAsFloats = new float[vertices.Count * 3]; + int vi = 0; + foreach (OMV.Vector3 vv in vertices) + { + // m_log.DebugFormat("{0}: {1}: <{2:0.00}, {3:0.00}, {4:0.00}>", LogHeader, vi / 3, vv.X, vv.Y, vv.Z); + verticesAsFloats[vi++] = vv.X; + verticesAsFloats[vi++] = vv.Y; + verticesAsFloats[vi++] = vv.Z; + } - // setup and do convex hull conversion - _hulls = new List(); - DecompDesc dcomp = new DecompDesc(); - dcomp.mIndices = convIndices; - dcomp.mVertices = convVertices; - ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); - // create the hull into the _hulls variable - convexBuilder.process(dcomp); - - // Convert the vertices and indices for passing to unmanaged - // The hull information is passed as a large floating point array. - // The format is: - // convHulls[0] = number of hulls - // convHulls[1] = number of vertices in first hull - // convHulls[2] = hull centroid X coordinate - // convHulls[3] = hull centroid Y coordinate - // convHulls[4] = hull centroid Z coordinate - // convHulls[5] = first hull vertex X - // convHulls[6] = first hull vertex Y - // convHulls[7] = first hull vertex Z - // convHulls[8] = second hull vertex X - // ... - // convHulls[n] = number of vertices in second hull - // convHulls[n+1] = second hull centroid X coordinate - // ... - // - // TODO: is is very inefficient. Someday change the convex hull generator to return - // data structures that do not need to be converted in order to pass to Bullet. - // And maybe put the values directly into pinned memory rather than marshaling. - int hullCount = _hulls.Count; - int totalVertices = 1; // include one for the count of the hulls - foreach (ConvexResult cr in _hulls) + // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", + // LogHeader, _localID, _meshKey, indices.Length, vertices.Count); + BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, + vertices.Count, verticesAsFloats); + + _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; + // meshes are already scaled by the meshmerizer + _scale = new OMV.Vector3(1f, 1f, 1f); + return; + } + + // No locking here because this is done when we know physics is not simulating + private void CreateGeomHull() + { + ulong newHullKey = (ulong)_pbs.GetHashCode(); + + // if the hull hasn't changed, don't rebuild it + if (newHullKey == _hullKey) return; + + // Since we're recreating new, get rid of any previously generated shape + if (_hullKey != 0) + { + // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); + BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); + _hullKey = 0; + _hulls.Clear(); + BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); + _mesh = null; // the mesh cannot match either + _meshKey = 0; + } + + _hullKey = newHullKey; + if (_meshKey != _hullKey) + { + // if the underlying mesh has changed, rebuild it + CreateGeomMesh(); + } + + int[] indices = _mesh.getIndexListAsInt(); + List vertices = _mesh.getVertexList(); + + //format conversion from IMesh format to DecompDesc format + List convIndices = new List(); + List convVertices = new List(); + for (int ii = 0; ii < indices.GetLength(0); ii++) + { + convIndices.Add(indices[ii]); + } + foreach (OMV.Vector3 vv in vertices) + { + convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); + } + + // setup and do convex hull conversion + _hulls = new List(); + DecompDesc dcomp = new DecompDesc(); + dcomp.mIndices = convIndices; + dcomp.mVertices = convVertices; + ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); + // create the hull into the _hulls variable + convexBuilder.process(dcomp); + + // Convert the vertices and indices for passing to unmanaged + // The hull information is passed as a large floating point array. + // The format is: + // convHulls[0] = number of hulls + // convHulls[1] = number of vertices in first hull + // convHulls[2] = hull centroid X coordinate + // convHulls[3] = hull centroid Y coordinate + // convHulls[4] = hull centroid Z coordinate + // convHulls[5] = first hull vertex X + // convHulls[6] = first hull vertex Y + // convHulls[7] = first hull vertex Z + // convHulls[8] = second hull vertex X + // ... + // convHulls[n] = number of vertices in second hull + // convHulls[n+1] = second hull centroid X coordinate + // ... + // + // TODO: is is very inefficient. Someday change the convex hull generator to return + // data structures that do not need to be converted in order to pass to Bullet. + // And maybe put the values directly into pinned memory rather than marshaling. + int hullCount = _hulls.Count; + int totalVertices = 1; // include one for the count of the hulls + foreach (ConvexResult cr in _hulls) + { + totalVertices += 4; // add four for the vertex count and centroid + totalVertices += cr.HullIndices.Count * 3; // we pass just triangles + } + float[] convHulls = new float[totalVertices]; + + convHulls[0] = (float)hullCount; + int jj = 1; + foreach (ConvexResult cr in _hulls) + { + // copy vertices for index access + float3[] verts = new float3[cr.HullVertices.Count]; + int kk = 0; + foreach (float3 ff in cr.HullVertices) { - totalVertices += 4; // add four for the vertex count and centroid - totalVertices += cr.HullIndices.Count * 3; // we pass just triangles + verts[kk++] = ff; } - float[] convHulls = new float[totalVertices]; - convHulls[0] = (float)hullCount; - int jj = 1; - foreach (ConvexResult cr in _hulls) + // add to the array one hull's worth of data + convHulls[jj++] = cr.HullIndices.Count; + convHulls[jj++] = 0f; // centroid x,y,z + convHulls[jj++] = 0f; + convHulls[jj++] = 0f; + foreach (int ind in cr.HullIndices) { - // copy vertices for index access - float3[] verts = new float3[cr.HullVertices.Count]; - int kk = 0; - foreach (float3 ff in cr.HullVertices) - { - verts[kk++] = ff; - } - - // add to the array one hull's worth of data - convHulls[jj++] = cr.HullIndices.Count; - convHulls[jj++] = 0f; // centroid x,y,z - convHulls[jj++] = 0f; - convHulls[jj++] = 0f; - foreach (int ind in cr.HullIndices) - { - convHulls[jj++] = verts[ind].x; - convHulls[jj++] = verts[ind].y; - convHulls[jj++] = verts[ind].z; - } + convHulls[jj++] = verts[ind].x; + convHulls[jj++] = verts[ind].y; + convHulls[jj++] = verts[ind].z; } - - // create the hull definition in Bullet - _hullKey = (ulong)_pbs.GetHashCode(); - // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); - BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); - _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; - // meshes are already scaled by the meshmerizer - _scale = new OMV.Vector3(1f, 1f, 1f); } + + // create the hull definition in Bullet + // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); + BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); + _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; + // meshes are already scaled by the meshmerizer + _scale = new OMV.Vector3(1f, 1f, 1f); return; } @@ -1040,6 +1133,7 @@ public sealed class BSPrim : PhysicsActor else { // simple object + // the mesh or hull must have already been created in Bullet ShapeData shape; FillShapeInfo(out shape); BulletSimAPI.CreateObject(_scene.WorldID, shape); @@ -1081,7 +1175,8 @@ public sealed class BSPrim : PhysicsActor shape.Scale = _scale; shape.Mass = _isPhysical ? _mass : 0f; shape.Buoyancy = _buoyancy; - shape.MeshKey = _hullKey; + shape.HullKey = _hullKey; + shape.MeshKey = _meshKey; shape.Friction = _friction; shape.Restitution = _restitution; shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; @@ -1098,13 +1193,13 @@ public sealed class BSPrim : PhysicsActor // remove any constraints that might be in place foreach (BSPrim prim in _childrenPrims) { - // m_log.DebugFormat("{0}: CreateObject: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); + // m_log.DebugFormat("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID); } // create constraints between the root prim and each of the children foreach (BSPrim prim in _childrenPrims) { - // m_log.DebugFormat("{0}: CreateObject: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); + // m_log.DebugFormat("{0}: CreateLinkset: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); // Zero motion for children so they don't interpolate prim.ZeroMotion(); @@ -1132,20 +1227,7 @@ public sealed class BSPrim : PhysicsActor // No locking here because this is done when the physics engine is not simulating private void RecreateGeomAndObject() { - // If this object is complex or we are the root of a linkset, build a mesh. - // The root of a linkset must be a mesh so we can create the linked compound object. - // if (_scene.NeedsMeshing(_pbs) || IsRootOfLinkset ) - if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh - { - // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); - _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.MeshLOD, _isPhysical); - } - else - { - // implement the shape with a Bullet native shape. - _mesh = null; - } - CreateGeom(); + CreateGeom(true); CreateObject(); return; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 518be09..e91455a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -37,7 +37,6 @@ using OpenMetaverse; using OpenSim.Region.Framework; // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Parameterize BulletSim. Pass a structure of parameters to the C++ code. Capsule size, friction, ... // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) // Test sculpties // Compute physics FPS reasonably @@ -52,8 +51,6 @@ using OpenSim.Region.Framework; // Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions) // Implement LockAngularMotion // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) -// Built Galton board (lots of MoveTo's) and some slats were not positioned correctly (mistakes scattered) -// No mistakes with ODE. Shape creation race condition? // Does NeedsMeshing() really need to exclude all the different shapes? // namespace OpenSim.Region.Physics.BulletSPlugin @@ -81,6 +78,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters { get { return m_meshLOD; } } + private int m_sculptLOD; + public int SculptLOD + { + get { return m_sculptLOD; } + } private int m_maxSubSteps; private float m_fixedTimeStep; @@ -187,7 +189,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters _meshSculptedPrim = true; // mesh sculpted prims _forceSimplePrimMeshing = false; // use complex meshing if called for - m_meshLOD = 32; + m_meshLOD = 8; + m_sculptLOD = 32; m_maxSubSteps = 10; m_fixedTimeStep = 1f / 60f; @@ -229,6 +232,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); m_meshLOD = pConfig.GetInt("MeshLevelOfDetail", m_meshLOD); + m_sculptLOD = pConfig.GetInt("SculptLevelOfDetail", m_sculptLOD); m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps); m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep); @@ -489,10 +493,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters // can use an internal representation for the prim if (!_forceSimplePrimMeshing) { - // m_log.DebugFormat("{0}: NeedsMeshing: simple mesh: profshape={1}, curve={2}", LogHeader, pbs.ProfileShape, pbs.PathCurve); if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 - && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) + && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) { if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 @@ -663,7 +666,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters #region Runtime settable parameters public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[] { - new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (Power of two. Default 32)"), + new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)"), + new PhysParameterEntry("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)"), new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"), new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"), new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"), @@ -712,6 +716,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters switch (lparm) { case "meshlod": m_meshLOD = (int)val; break; + case "sculptlod": m_sculptLOD = (int)val; break; case "maxsubstep": m_maxSubSteps = (int)val; break; case "fixedtimestep": m_fixedTimeStep = val; break; case "maxobjectmass": m_maximumObjectMass = val; break; @@ -812,6 +817,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters switch (parm.ToLower()) { case "meshlod": val = (float)m_meshLOD; break; + case "sculptlod": val = (float)m_sculptLOD; break; case "maxsubstep": val = (float)m_maxSubSteps; break; case "fixedtimestep": val = m_fixedTimeStep; break; case "maxobjectmass": val = m_maximumObjectMass; break; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index bf953df..a610c8d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -49,7 +49,8 @@ public struct ShapeData SHAPE_CONE = 2, SHAPE_CYLINDER = 3, SHAPE_SPHERE = 4, - SHAPE_HULL = 5 + SHAPE_MESH = 5, + SHAPE_HULL = 6 }; public uint ID; public PhysicsShapeType Type; @@ -59,6 +60,7 @@ public struct ShapeData public Vector3 Scale; public float Mass; public float Buoyancy; + public System.UInt64 HullKey; public System.UInt64 MeshKey; public float Friction; public float Restitution; @@ -158,20 +160,29 @@ public static extern void Shutdown(uint worldID); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool CreateHull(uint worldID, System.UInt64 meshKey, int hullCount, - [MarshalAs(UnmanagedType.LPArray)] float[] hulls +public static extern bool CreateHull(uint worldID, System.UInt64 meshKey, + int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls + ); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool CreateMesh(uint worldID, System.UInt64 meshKey, + int indexCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, + int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool DestroyHull(uint worldID, System.UInt64 meshKey); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool CreateObject(uint worldID, ShapeData shapeData); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -179,9 +190,9 @@ public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void AddConstraint(uint worldID, uint id1, uint id2, - Vector3 frame1, Quaternion frame1rot, - Vector3 frame2, Quaternion frame2rot, - Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); + Vector3 frame1, Quaternion frame1rot, + Vector3 frame2, Quaternion frame2rot, + Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool RemoveConstraintByID(uint worldID, uint id1); -- cgit v1.1 From 33a894f3d2cc95a7a512b86f39f3c6a6afabb015 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 27 Aug 2011 00:15:21 +0100 Subject: refactor: move SOP.IsAttachment and AttachmentPoint up into SOG to avoid pointless duplication of identical values --- .../Caps/ObjectCaps/UploadObjectAssetModule.cs | 2 +- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 10 +++-- .../Avatar/Attachments/AttachmentsModule.cs | 13 +++--- .../Attachments/Tests/AttachmentsModuleTests.cs | 18 ++++----- .../EntityTransfer/EntityTransferModule.cs | 2 +- .../InventoryAccess/InventoryAccessModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 8 ++-- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 44 +++++++++------------ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 46 ++++++---------------- .../Framework/Scenes/SceneObjectPartInventory.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 ++-- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 3 +- .../Shared/Api/Implementation/LSL_Api.cs | 20 +++++----- .../Api/Implementation/Plugins/SensorRepeat.cs | 8 ++-- 15 files changed, 81 insertions(+), 109 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 8189518..c07fc73 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -330,7 +330,7 @@ namespace OpenSim.Region.ClientStack.Linden grp.AbsolutePosition = obj.Position; prim.RotationOffset = obj.Rotation; - grp.RootPart.IsAttachment = false; + grp.IsAttachment = false; // Required for linking grp.RootPart.UpdateFlag = 0; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f71871e..dc9a6ed 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4756,7 +4756,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP { SceneObjectPart part = (SceneObjectPart)entity; - attachPoint = part.AttachmentPoint; + if (part.ParentGroup != null) + attachPoint = part.ParentGroup.AttachmentPoint; + else + attachPoint = 0; + collisionPlane = Vector4.Zero; position = part.RelativePosition; velocity = part.Velocity; @@ -4913,10 +4917,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP //update.JointType = 0; update.Material = data.Material; update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim - if (data.IsAttachment) + if (data.ParentGroup != null && data.ParentGroup.IsAttachment) { update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); - update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); + update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); } else { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 3e1cb02..b976020 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -369,11 +369,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments SceneObjectGroup att, ScenePresence sp, UUID itemID, uint AttachmentPt) { // m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", -// remoteClient.Name, att.Name, itemID); +// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}", +// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt); if (!att.IsDeleted) - AttachmentPt = att.RootPart.AttachmentPoint; + AttachmentPt = att.AttachmentPoint; InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); item = m_scene.InventoryService.GetItem(item); @@ -547,7 +547,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ); group.RootPart.SetParentLocalId(0); - group.RootPart.IsAttachment = false; + group.IsAttachment = false; group.AbsolutePosition = group.RootPart.AttachedPos; UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); @@ -569,7 +569,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Finally, we restore the object's attachment status. byte attachmentPoint = sog.GetAttachmentPoint(); sog.UpdateGroupPosition(pos); - sog.RootPart.IsAttachment = false; + sog.IsAttachment = false; sog.AbsolutePosition = sog.RootPart.AttachedPos; sog.SetAttachmentPoint(attachmentPoint); sog.HasGroupChanged = true; @@ -666,8 +666,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.AbsolutePosition = attachOffset; so.RootPart.AttachedPos = attachOffset; - so.RootPart.IsAttachment = true; - + so.IsAttachment = true; so.RootPart.SetParentLocalId(avatar.LocalId); so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b7d21fd..790a651 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -110,6 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); @@ -132,9 +133,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); @@ -145,6 +145,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); @@ -166,9 +167,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); @@ -198,9 +198,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); @@ -242,6 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f5d49c5..7963e53 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1782,7 +1782,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Set the parent localID to 0 so it transfers over properly. gobj.RootPart.SetParentLocalId(0); gobj.AbsolutePosition = gobj.RootPart.AttachedPos; - gobj.RootPart.IsAttachment = false; + gobj.IsAttachment = false; //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); CrossPrimGroupIntoNewRegion(destination, gobj, silent); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 65ba87b..fcb7eea 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -841,7 +841,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; - group.RootPart.IsAttachment = true; + group.IsAttachment = true; } // If we're rezzing an attachment then don't ask diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 2a76755..33407ec 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) + if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) + if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -148,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) + if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -171,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { // Attachments are high priority, - if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) + if (((SceneObjectPart)entity).ParentGroup.IsAttachment) return 1; // Non physical prims are lower priority than physical prims diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 513c0ea..45d1a0e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4223,7 +4223,7 @@ namespace OpenSim.Region.Framework.Scenes // their scripts will actually run. // -- Leaf, Tue Aug 12 14:17:05 EDT 2008 SceneObjectPart parent = part.ParentGroup.RootPart; - if (parent != null && parent.IsAttachment) + if (parent != null && part.ParentGroup.IsAttachment) return ScriptDanger(parent, parent.GetWorldPosition()); else return ScriptDanger(part, part.GetWorldPosition()); @@ -5030,7 +5030,7 @@ namespace OpenSim.Region.Framework.Scenes delete = true; } - if (delete && !rootPart.IsAttachment && !deletes.Contains(g)) + if (delete && !g.IsAttachment && !deletes.Contains(g)) deletes.Add(g); }); break; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fada688..34f484d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -146,27 +146,11 @@ namespace OpenSim.Region.Framework.Scenes return true; return false; } - + /// /// Is this scene object acting as an attachment? /// - /// - /// We return false if the group has already been deleted. - /// - /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I - /// presume either all or no parts in a linkset can be part of an attachment (in which - /// case the value would get proprogated down into all the descendent parts). - /// - public bool IsAttachment - { - get - { - if (!IsDeleted) - return m_rootPart.IsAttachment; - - return false; - } - } + public bool IsAttachment { get; set; } /// /// The avatar to which this scene object is attached. @@ -177,6 +161,14 @@ namespace OpenSim.Region.Framework.Scenes public UUID AttachedAvatar { get; set; } /// + /// Attachment point of this scene object to an avatar. + /// + /// + /// 0 if we're not attached to anything + /// + public uint AttachmentPoint; + + /// /// Is this scene object phantom? /// /// @@ -354,11 +346,13 @@ namespace OpenSim.Region.Framework.Scenes /// /// Check both the attachment property and the relevant properties of the underlying root part. /// + /// /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't /// have the IsAttachment property yet checked. /// /// FIXME: However, this should be fixed so that this property /// propertly reflects the underlying status. + /// /// public bool IsAttachmentCheckFull() { @@ -987,11 +981,11 @@ namespace OpenSim.Region.Framework.Scenes return m_rootPart.Shape.State; } - public void SetAttachmentPoint(byte point) + public void SetAttachmentPoint(uint point) { - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].SetAttachmentPoint(point); + AttachmentPoint = point; + IsAttachment = point != 0; + m_rootPart.Shape.State = (byte)point; } public void ClearPartAttachmentData() @@ -1424,16 +1418,16 @@ namespace OpenSim.Region.Framework.Scenes // This is only necessary when userExposed is false! - bool previousAttachmentStatus = dupe.RootPart.IsAttachment; + bool previousAttachmentStatus = dupe.IsAttachment; if (!userExposed) - dupe.RootPart.IsAttachment = true; + dupe.IsAttachment = true; dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); if (!userExposed) { - dupe.RootPart.IsAttachment = previousAttachmentStatus; + dupe.IsAttachment = previousAttachmentStatus; } dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e510611..71023a9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -213,10 +213,7 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_fromUserInventoryItemID; } } - - public bool IsAttachment; - public scriptEvents AggregateScriptEvents; @@ -224,9 +221,6 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 AttachedPos; - public uint AttachmentPoint; - - public Vector3 RotationAxis = Vector3.One; @@ -723,7 +717,7 @@ namespace OpenSim.Region.Framework.Scenes m_groupPosition = actor.Position; } - if (IsAttachment) + if (m_parentGroup.IsAttachment) { ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); if (sp != null) @@ -807,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes { if (IsRoot) { - if (IsAttachment) + if (m_parentGroup.IsAttachment) return AttachedPos; else return AbsolutePosition; @@ -1090,7 +1084,7 @@ namespace OpenSim.Region.Framework.Scenes { get { - if (IsAttachment) + if (m_parentGroup.IsAttachment) return GroupPosition; return m_offsetPosition + m_groupPosition; @@ -1588,7 +1582,7 @@ namespace OpenSim.Region.Framework.Scenes // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition // or flexible - if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) + if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) { try { @@ -2880,7 +2874,7 @@ namespace OpenSim.Region.Framework.Scenes public void rotLookAt(Quaternion target, float strength, float damping) { - if (IsAttachment) + if (m_parentGroup.IsAttachment) { /* ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); @@ -3014,7 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes if (IsRoot) { - if (IsAttachment) + if (m_parentGroup.IsAttachment) { SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); } @@ -3076,7 +3070,7 @@ namespace OpenSim.Region.Framework.Scenes { // Suppress full updates during attachment editing // - if (ParentGroup.IsSelected && IsAttachment) + if (ParentGroup.IsSelected && ParentGroup.IsAttachment) return; if (ParentGroup.IsDeleted) @@ -3254,26 +3248,6 @@ namespace OpenSim.Region.Framework.Scenes }); } - public void SetAttachmentPoint(uint AttachmentPoint) - { - this.AttachmentPoint = AttachmentPoint; - - if (AttachmentPoint != 0) - { - IsAttachment = true; - } - else - { - IsAttachment = false; - } - - // save the attachment point. - //if (AttachmentPoint != 0) - //{ - m_shape.State = (byte)AttachmentPoint; - //} - } - public void SetAxisRotation(int axis, int rotate) { if (m_parentGroup != null) @@ -4497,7 +4471,9 @@ namespace OpenSim.Region.Framework.Scenes } } - if (SetPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints + if (SetPhantom + || ParentGroup.IsAttachment + || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); if (PhysActor != null) @@ -4928,7 +4904,7 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup == null || ParentGroup.IsDeleted) return; - if (IsAttachment && ParentGroup.RootPart != this) + if (ParentGroup.IsAttachment && ParentGroup.RootPart != this) return; // Causes this thread to dig into the Client Thread Data. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3b60f8c..108089e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -201,7 +201,7 @@ namespace OpenSim.Region.Framework.Scenes // Don't let this set the HasGroupChanged flag for attachments // as this happens during rez and we don't want a new asset // for each attachment each time - if (!m_part.ParentGroup.RootPart.IsAttachment) + if (!m_part.ParentGroup.IsAttachment) { HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fc89473..93782ce 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3178,7 +3178,7 @@ namespace OpenSim.Region.Framework.Scenes ISceneObject clone = sog.CloneForNewScene(); // Attachment module assumes that GroupPosition holds the offsets...! ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; - ((SceneObjectGroup)clone).RootPart.IsAttachment = false; + ((SceneObjectGroup)clone).IsAttachment = false; cAgent.AttachmentObjects.Add(clone); string state = sog.GetStateSnapshot(); cAgent.AttachmentObjectStates.Add(state); @@ -3477,7 +3477,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectGroup so in m_attachments) { - if (attachmentPoint == so.RootPart.AttachmentPoint) + if (attachmentPoint == so.AttachmentPoint) attachments.Add(so); } } @@ -3869,12 +3869,12 @@ namespace OpenSim.Region.Framework.Scenes { if (grp.HasGroupChanged) // Resizer scripts? { - grp.RootPart.IsAttachment = false; + grp.IsAttachment = false; grp.AbsolutePosition = grp.RootPart.AttachedPos; // grp.DetachToInventoryPrep(); attachmentsModule.UpdateKnownItem(ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); - grp.RootPart.IsAttachment = true; + grp.IsAttachment = true; } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 7c067ca..997845b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -120,8 +120,7 @@ namespace OpenSim.Region.Framework.Scenes // We deal with the possibility that two updates occur at // the same unix time at the update point itself. - if ((update.LastFullUpdateTime < part.TimeStampFull) || - part.IsAttachment) + if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 81f1f38..a7f08d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1965,7 +1965,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part.ParentGroup.RootPart == part) { - if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) + if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) targetPos.z = ground; SceneObjectGroup parent = part.ParentGroup; LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); @@ -2097,7 +2097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Quaternion q; if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim { - if (part.ParentGroup.RootPart.AttachmentPoint != 0) + if (part.ParentGroup.AttachmentPoint != 0) { ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar); if (avatar != null) @@ -2241,7 +2241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Vector3 vel; - if (m_host.IsAttachment) + if (m_host.ParentGroup.IsAttachment) { ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); vel = avatar.Velocity; @@ -2997,7 +2997,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) + if (m_host.ParentGroup.AttachmentPoint == 0) return; TaskInventoryItem item; @@ -3587,7 +3587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); - if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) + if (targetPart.ParentGroup.AttachmentPoint != 0) return; // Fail silently if attached SceneObjectGroup parentPrim = null, childPrim = null; @@ -3640,7 +3640,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectGroup parentPrim = m_host.ParentGroup; - if (parentPrim.RootPart.AttachmentPoint != 0) + if (parentPrim.AttachmentPoint != 0) return; // Fail silently if attached SceneObjectPart childPrim = null; @@ -3710,7 +3710,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); SceneObjectGroup parentPrim = m_host.ParentGroup; - if (parentPrim.RootPart.AttachmentPoint != 0) + if (parentPrim.AttachmentPoint != 0) return; // Fail silently if attached List parts = new List(parentPrim.Parts); @@ -4349,7 +4349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; // Object not pushable. Not an attachment and has no physics component - if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) + if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null) return; PusheePos = pusheeob.AbsolutePosition; @@ -5857,7 +5857,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetAttached() { m_host.AddScriptLPS(1); - return m_host.ParentGroup.RootPart.AttachmentPoint; + return m_host.ParentGroup.AttachmentPoint; } public LSL_Integer llGetFreeMemory() @@ -7458,7 +7458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); Quaternion q; - if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) + if (m_host.ParentGroup.AttachmentPoint != 0) { ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); if (avatar != null) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index bf74760..4ac7f8b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -303,7 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins float dz; Quaternion q = SensePoint.RotationOffset; - if (SensePoint.ParentGroup.RootPart.IsAttachment) + if (SensePoint.ParentGroup.IsAttachment) { // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if @@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins objtype = 0; part = ((SceneObjectGroup)ent).RootPart; - if (part.AttachmentPoint != 0) // Attached so ignore + if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore continue; if (part.Inventory.ContainsScripts()) @@ -423,7 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins Vector3 fromRegionPos = SensePoint.AbsolutePosition; Quaternion q = SensePoint.RotationOffset; - if (SensePoint.ParentGroup.RootPart.IsAttachment) + if (SensePoint.ParentGroup.IsAttachment) { // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if @@ -435,7 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); - bool attached = (SensePoint.AttachmentPoint != 0); + bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); Vector3 toRegionPos; double dis; -- cgit v1.1 From b7700428ec298f29ae4cbb0e1090728fe3b93602 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 27 Aug 2011 00:20:15 +0100 Subject: refactor: camel case AttachmentPoint method arg as per code standards --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b976020..d9259b3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -363,22 +363,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - /// + /// /// private UUID ShowAttachInUserInventory( - SceneObjectGroup att, ScenePresence sp, UUID itemID, uint AttachmentPt) + SceneObjectGroup att, ScenePresence sp, UUID itemID, uint attachmentPoint) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}", // sp.Name, att.Name, att.LocalId, itemID, AttachmentPt); if (!att.IsDeleted) - AttachmentPt = att.AttachmentPoint; + attachmentPoint = att.AttachmentPoint; InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); item = m_scene.InventoryService.GetItem(item); - bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); + bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); -- cgit v1.1 From 1615e7d29fb6961a3ffe791fde4318f819c1a4b7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 27 Aug 2011 00:33:24 +0100 Subject: Eliminate duplicate AttachmentPoint properties by always using the one stored in the root part's state field. --- .../Avatar/Attachments/AttachmentsModule.cs | 42 +++++++++++----------- .../Attachments/Tests/AttachmentsModuleTests.cs | 3 -- .../Region/CoreModules/World/Sound/SoundModule.cs | 4 +-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 36 +++++++++---------- 4 files changed, 41 insertions(+), 44 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d9259b3..2d5eb18 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -167,13 +167,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return AttachObject(sp, group, AttachmentPt, silent); } - private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) + private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // group.Name, group.LocalId, sp.Name, AttachmentPt, silent); - if (sp.GetAttachments(AttachmentPt).Contains(group)) + if (sp.GetAttachments(attachmentPt).Contains(group)) { // m_log.WarnFormat( // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", @@ -186,39 +186,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim - AttachmentPt &= 0x7f; + attachmentPt &= 0x7f; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. - if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) + if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) { attachPos = Vector3.Zero; } // AttachmentPt 0 means the client chose to 'wear' the attachment. - if (AttachmentPt == 0) + if (attachmentPt == 0) { // Check object for stored attachment point - AttachmentPt = (uint)group.GetAttachmentPoint(); + attachmentPt = group.AttachmentPoint; } // if we still didn't find a suitable attachment point....... - if (AttachmentPt == 0) + if (attachmentPt == 0) { // Stick it on left hand with Zero Offset from the attachment point. - AttachmentPt = (uint)AttachmentPoint.LeftHand; + attachmentPt = (uint)AttachmentPoint.LeftHand; attachPos = Vector3.Zero; } - group.SetAttachmentPoint((byte)AttachmentPt); + group.AttachmentPoint = attachmentPt; group.AbsolutePosition = attachPos; // Remove any previous attachments UUID itemID = UUID.Zero; foreach (SceneObjectGroup grp in sp.Attachments) { - if (grp.GetAttachmentPoint() == (byte)AttachmentPt) + if (grp.AttachmentPoint == attachmentPt) { itemID = grp.GetFromItemID(); break; @@ -232,9 +232,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (itemID == UUID.Zero) itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; - ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); + ShowAttachInUserInventory(sp, attachmentPt, itemID, group); - AttachToAgent(sp, group, AttachmentPt, attachPos, silent); + AttachToAgent(sp, group, attachmentPt, attachPos, silent); return true; } @@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - ScenePresence sp, UUID itemID, uint AttachmentPt) + ScenePresence sp, UUID itemID, uint attachmentPt) { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) @@ -313,13 +313,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // since scripts aren't running yet. So, clear it here. objatt.HasGroupChanged = false; bool tainted = false; - if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) + if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) tainted = true; // This will throw if the attachment fails try { - AttachObject(sp, objatt, AttachmentPt, false); + AttachObject(sp, objatt, attachmentPt, false); } catch (Exception e) { @@ -348,7 +348,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_log.WarnFormat( "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, sp.Name, AttachmentPt); + itemID, sp.Name, attachmentPt); } return objatt; @@ -567,11 +567,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // attachment. This is necessary in order to correctly save // and retrieve GroupPosition information for the attachment. // Finally, we restore the object's attachment status. - byte attachmentPoint = sog.GetAttachmentPoint(); + uint attachmentPoint = sog.AttachmentPoint; sog.UpdateGroupPosition(pos); sog.IsAttachment = false; sog.AbsolutePosition = sog.RootPart.AttachedPos; - sog.SetAttachmentPoint(attachmentPoint); + sog.AttachmentPoint = attachmentPoint; sog.HasGroupChanged = true; } @@ -594,14 +594,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_log.DebugFormat( "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", - grp.UUID, grp.GetAttachmentPoint()); + grp.UUID, grp.AttachmentPoint); return; } m_log.DebugFormat( "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", - grp.UUID, grp.GetAttachmentPoint()); + grp.UUID, grp.AttachmentPoint); string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); @@ -668,7 +668,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.RootPart.AttachedPos = attachOffset; so.IsAttachment = true; so.RootPart.SetParentLocalId(avatar.LocalId); - so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); + so.AttachmentPoint = attachmentpoint; avatar.AddAttachment(so); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 790a651..bb53601 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -111,7 +111,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); - Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); @@ -146,7 +145,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); - Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); @@ -242,7 +240,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); - Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 09c0ebb..22ffcd6 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Sound if (grp.IsAttachment) { - if (grp.GetAttachmentPoint() > 30) // HUD + if (grp.AttachmentPoint > 30) // HUD { if (sp.ControllingClient.AgentId != grp.OwnerID) return; @@ -115,7 +115,7 @@ namespace OpenSim.Region.CoreModules.World.Sound { SceneObjectGroup grp = part.ParentGroup; - if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) + if (grp.IsAttachment && grp.AttachmentPoint > 30) { objectID = ownerID; parentID = ownerID; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 34f484d..c453366 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -166,7 +166,24 @@ namespace OpenSim.Region.Framework.Scenes /// /// 0 if we're not attached to anything /// - public uint AttachmentPoint; + public uint AttachmentPoint + { + get + { + return m_rootPart.Shape.State; + } + + set + { + IsAttachment = value != 0; + m_rootPart.Shape.State = (byte)value; + } + } + + public void ClearPartAttachmentData() + { + AttachmentPoint = 0; + } /// /// Is this scene object phantom? @@ -976,23 +993,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public byte GetAttachmentPoint() - { - return m_rootPart.Shape.State; - } - - public void SetAttachmentPoint(uint point) - { - AttachmentPoint = point; - IsAttachment = point != 0; - m_rootPart.Shape.State = (byte)point; - } - - public void ClearPartAttachmentData() - { - SetAttachmentPoint((Byte)0); - } - /// /// /// -- cgit v1.1 From d4d894c20f3a44783172f8e52385d871b03e1aef Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 27 Aug 2011 01:28:33 +0100 Subject: Stop avatars returning from neighbouring regions from stalling on the border crossing. On making a root agent, we need to reset the ScenePresence.m_movement_flag so that it doesn't remember the movement registered to the client when it exited the initial region. If this is remember, then the client avatar movement isn't updated and it appears to stall in mid-air, though this is resolved with a prod/release of any other direction key. This bug was probably introduced a few weeks ago. Surprised that nobody brought it up. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 93782ce..4148d4b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -965,6 +965,11 @@ namespace OpenSim.Region.Framework.Scenes presence.Animator.SendAnimPackToClient(ControllingClient); }); + // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will + // stall on the border crossing since the existing child agent will still have the last movement + // recorded, which stops the input from being processed. + m_movementflag = 0; + m_scene.EventManager.TriggerOnMakeRootAgent(this); } @@ -1247,6 +1252,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { +// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); + //if (m_isChildAgent) //{ // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); @@ -1445,6 +1452,8 @@ namespace OpenSim.Region.Framework.Scenes { m_movementflag |= (byte)nudgehack; } + +// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); m_movementflag += (byte)(uint)DCF; update_movementflag = true; } @@ -1456,6 +1465,7 @@ namespace OpenSim.Region.Framework.Scenes && ((m_movementflag & (byte)nudgehack) == nudgehack)) ) // This or is for Nudge forward { +// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); m_movementflag -= ((byte)(uint)DCF); update_movementflag = true; @@ -1520,12 +1530,21 @@ namespace OpenSim.Region.Framework.Scenes // which occurs later in the main scene loop if (update_movementflag || (update_rotation && DCFlagKeyPressed)) { - // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); - // m_log.DebugFormat( - // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", +// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); AddNewMovement(agent_control_v3); } +// else +// { +// if (!update_movementflag) +// { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", +// m_scene.RegionInfo.RegionName, agent_control_v3, Name); +// } +// } if (update_movementflag && m_parentID == 0) Animator.UpdateMovementAnimations(); -- cgit v1.1 From 795b56e695976575eacfd5505830a94f32ca2d28 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Sat, 27 Aug 2011 12:16:46 +0900 Subject: Related to #4689 - Adding missing null check for SceneObjectPart Signed-off-by: BlueWall --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 8 ++++++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 14 ++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9358e7b..addc20c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -223,6 +223,8 @@ namespace OpenSim.Region.Framework.Scenes // Retrieve group SceneObjectPart part = GetSceneObjectPart(primId); + if (part == null) + return new ArrayList(); SceneObjectGroup group = part.ParentGroup; if (null == group) { @@ -967,6 +969,8 @@ namespace OpenSim.Region.Framework.Scenes public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) { SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + return; SceneObjectGroup group = part.ParentGroup; if (group != null) { @@ -2028,6 +2032,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in localIDs) { SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + continue; if (!groups.Contains(part.ParentGroup)) groups.Add(part.ParentGroup); } @@ -2073,6 +2079,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in localIDs) { SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + continue; part.GetProperties(remoteClient); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f40b373..0582586 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1546,8 +1546,11 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); - part.ClickAction = Convert.ToByte(clickAction); - group.HasGroupChanged = true; + if (part != null) + { + part.ClickAction = Convert.ToByte(clickAction); + group.HasGroupChanged = true; + } } } } @@ -1560,8 +1563,11 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); - part.Material = Convert.ToByte(material); - group.HasGroupChanged = true; + if (part != null) + { + part.Material = Convert.ToByte(material); + group.HasGroupChanged = true; + } } } } -- cgit v1.1 From 80a2b81d52de3c053ce00f1f54751c7a931dad23 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Aug 2011 21:26:26 -0700 Subject: Add level of detail specification to optionally reduce the number of vertices in generated prim meshes Signed-off-by: BlueWall --- OpenSim/Region/Physics/Manager/IMesher.cs | 11 ++++++++ OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 36 +++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 1181b8d..3a9ca1b 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -38,6 +38,17 @@ namespace OpenSim.Region.Physics.Manager IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); } + // Values for level of detail to be passed to the mesher. + // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture) + // Lower level of detail reduces the number of vertices used to represent the meshed shape. + public enum LevelOfDetail + { + High = 32, + Medium = 16, + Low = 8, + VeryLow = 4 + } + public interface IVertex { } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index e81b982..faecce4 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -336,7 +336,7 @@ namespace OpenSim.Region.Physics.Meshing } else { - if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) + if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces)) return null; } @@ -616,7 +616,7 @@ namespace OpenSim.Region.Physics.Meshing /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimShapeData( - string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) + string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) { PrimMesh primMesh; coords = new List(); @@ -636,13 +636,30 @@ namespace OpenSim.Region.Physics.Meshing profileHollow = 0.95f; int sides = 4; + LevelOfDetail iLOD = (LevelOfDetail)lod; if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) sides = 3; else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - sides = 24; + { + switch (iLOD) + { + case LevelOfDetail.High: sides = 24; break; + case LevelOfDetail.Medium: sides = 12; break; + case LevelOfDetail.Low: sides = 6; break; + case LevelOfDetail.VeryLow: sides = 3; break; + default: sides = 24; break; + } + } else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) { // half circle, prim is a sphere - sides = 24; + switch (iLOD) + { + case LevelOfDetail.High: sides = 24; break; + case LevelOfDetail.Medium: sides = 12; break; + case LevelOfDetail.Low: sides = 6; break; + case LevelOfDetail.VeryLow: sides = 3; break; + default: sides = 24; break; + } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; @@ -650,7 +667,16 @@ namespace OpenSim.Region.Physics.Meshing int hollowSides = sides; if (primShape.HollowShape == HollowShape.Circle) - hollowSides = 24; + { + switch (iLOD) + { + case LevelOfDetail.High: hollowSides = 24; break; + case LevelOfDetail.Medium: hollowSides = 12; break; + case LevelOfDetail.Low: hollowSides = 6; break; + case LevelOfDetail.VeryLow: hollowSides = 3; break; + default: hollowSides = 24; break; + } + } else if (primShape.HollowShape == HollowShape.Square) hollowSides = 4; else if (primShape.HollowShape == HollowShape.Triangle) -- cgit v1.1 From 18037d41c45b7a00170a7badddd3ef1d8ad2a25c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Aug 2011 20:51:05 -0700 Subject: Move GetMeshKey from buried inside Meshmerizer to a public method on PrimitiveBaseShape Signed-off-by: BlueWall --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 63 +-------------------------- 1 file changed, 1 insertion(+), 62 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index faecce4..53d5e4c 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -193,67 +193,6 @@ namespace OpenSim.Region.Physics.Meshing m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); } - private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod) - { - ulong hash = 5381; - - hash = djb2(hash, pbs.PathCurve); - hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape)); - hash = djb2(hash, pbs.PathBegin); - hash = djb2(hash, pbs.PathEnd); - hash = djb2(hash, pbs.PathScaleX); - hash = djb2(hash, pbs.PathScaleY); - hash = djb2(hash, pbs.PathShearX); - hash = djb2(hash, pbs.PathShearY); - hash = djb2(hash, (byte)pbs.PathTwist); - hash = djb2(hash, (byte)pbs.PathTwistBegin); - hash = djb2(hash, (byte)pbs.PathRadiusOffset); - hash = djb2(hash, (byte)pbs.PathTaperX); - hash = djb2(hash, (byte)pbs.PathTaperY); - hash = djb2(hash, pbs.PathRevolutions); - hash = djb2(hash, (byte)pbs.PathSkew); - hash = djb2(hash, pbs.ProfileBegin); - hash = djb2(hash, pbs.ProfileEnd); - hash = djb2(hash, pbs.ProfileHollow); - - // TODO: Separate scale out from the primitive shape data (after - // scaling is supported at the physics engine level) - byte[] scaleBytes = size.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); - - // Include LOD in hash, accounting for endianness - byte[] lodBytes = new byte[4]; - Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4); - if (!BitConverter.IsLittleEndian) - { - Array.Reverse(lodBytes, 0, 4); - } - for (int i = 0; i < lodBytes.Length; i++) - hash = djb2(hash, lodBytes[i]); - - // include sculpt UUID - if (pbs.SculptEntry) - { - scaleBytes = pbs.SculptTexture.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); - } - - return hash; - } - - private ulong djb2(ulong hash, byte c) - { - return ((hash << 5) + hash) + (ulong)c; - } - - private ulong djb2(ulong hash, ushort c) - { - hash = ((hash << 5) + hash) + (ulong)((byte)c); - return ((hash << 5) + hash) + (ulong)(c >> 8); - } - /// /// Add a submesh to an existing list of coords and faces. /// @@ -777,7 +716,7 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - key = GetMeshKey(primShape, size, lod); + key = primShape.GetMeshKey(size, lod); if (m_uniqueMeshes.TryGetValue(key, out mesh)) return mesh; -- cgit v1.1 From 96dce3e16c3c0b861e42e6331f693b6b00a14392 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 29 Aug 2011 10:00:58 -0700 Subject: Use GetMeshKey from PrimitiveBaseShape. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 22 +++++++++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 16 ++++++++-------- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d1fb576..bb8d601 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -53,8 +53,11 @@ public sealed class BSPrim : PhysicsActor private String _avName; private uint _localID = 0; - private OMV.Vector3 _size; - private OMV.Vector3 _scale; + // _size is what the user passed. _scale is what we pass to the physics engine with the mesh. + // Often _scale is unity because the meshmerizer will apply _size when creating the mesh. + private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user + private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer + private bool _stopped; private bool _grabbed; private bool _isSelected; @@ -460,6 +463,7 @@ public sealed class BSPrim : PhysicsActor // no locking here because only called when it is safe private void SetObjectDynamic() { + // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); // non-physical things work best with a mass of zero if (IsStatic) { @@ -474,7 +478,6 @@ public sealed class BSPrim : PhysicsActor } BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); - // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}, mass={4}", LogHeader, _localID, IsStatic, IsSolid, _mass); } // prims don't fly @@ -955,7 +958,9 @@ public sealed class BSPrim : PhysicsActor // No locking here because this is done when we know physics is not simulating private void CreateGeomMesh() { - ulong newMeshKey = (ulong)_pbs.GetHashCode(); + float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; + ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); + // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); // if this new shape is the same as last time, don't recreate the mesh if (_meshKey == newMeshKey) return; @@ -963,14 +968,13 @@ public sealed class BSPrim : PhysicsActor // Since we're recreating new, get rid of any previously generated shape if (_meshKey != 0) { - // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _meshKey); + // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; _meshKey = 0; } _meshKey = newMeshKey; - int lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; // always pass false for physicalness as this creates some sort of bounding box which we don't need _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, lod, false); @@ -1001,7 +1005,9 @@ public sealed class BSPrim : PhysicsActor // No locking here because this is done when we know physics is not simulating private void CreateGeomHull() { - ulong newHullKey = (ulong)_pbs.GetHashCode(); + float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; + ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod); + // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey); // if the hull hasn't changed, don't rebuild it if (newHullKey == _hullKey) return; @@ -1136,6 +1142,7 @@ public sealed class BSPrim : PhysicsActor // the mesh or hull must have already been created in Bullet ShapeData shape; FillShapeInfo(out shape); + // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); BulletSimAPI.CreateObject(_scene.WorldID, shape); } } @@ -1227,6 +1234,7 @@ public sealed class BSPrim : PhysicsActor // No locking here because this is done when the physics engine is not simulating private void RecreateGeomAndObject() { + // m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID); CreateGeom(true); CreateObject(); return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e91455a..7704002 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -73,13 +73,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters private bool m_initialized = false; public IMesher mesher; - private int m_meshLOD; - public int MeshLOD + private float m_meshLOD; + public float MeshLOD { get { return m_meshLOD; } } - private int m_sculptLOD; - public int SculptLOD + private float m_sculptLOD; + public float SculptLOD { get { return m_sculptLOD; } } @@ -189,8 +189,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters _meshSculptedPrim = true; // mesh sculpted prims _forceSimplePrimMeshing = false; // use complex meshing if called for - m_meshLOD = 8; - m_sculptLOD = 32; + m_meshLOD = 8f; + m_sculptLOD = 32f; m_maxSubSteps = 10; m_fixedTimeStep = 1f / 60f; @@ -231,8 +231,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); - m_meshLOD = pConfig.GetInt("MeshLevelOfDetail", m_meshLOD); - m_sculptLOD = pConfig.GetInt("SculptLevelOfDetail", m_sculptLOD); + m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD); + m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD); m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps); m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep); -- cgit v1.1 From be357f8feeb438e3292292d163918a307d69c69a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 01:58:32 +0100 Subject: Fix bug in persisting saved appearances for npcs Assets have to be marked non-local as well as non-temporary to persist. This is now done. Hopefully addresses http://opensimulator.org/mantis/view.php?id=5660 --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 1 - .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 48 ++++++++++++++++---- .../Tests/AvatarFactoryModuleTests.cs | 51 ++++++++++++++++++++++ .../Asset/LocalAssetServiceConnector.cs | 25 ++++++++--- .../Region/Framework/Interfaces/IAvatarFactory.cs | 17 ++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +-- 6 files changed, 131 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index ff889ea..d1ce5df 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -136,7 +136,6 @@ namespace OpenSim.Region.ClientStack.Linden TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS; GetClient = m_Scene.SceneContents.GetControllingClient; - } /// diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 4627701..f34b6d2 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -257,20 +257,27 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return true; } - public bool SaveBakedTextures(UUID agentId) + public Dictionary GetBakedTextureFaces(UUID agentId) { ScenePresence sp = m_scene.GetScenePresence(agentId); - if (sp == null || sp.IsChildAgent) - return false; + if (sp == null) + return new Dictionary(); + + return GetBakedTextureFaces(sp); + } + + private Dictionary GetBakedTextureFaces(ScenePresence sp) + { + if (sp.IsChildAgent) + return new Dictionary(); + + Dictionary bakedTextures + = new Dictionary(); AvatarAppearance appearance = sp.Appearance; Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures; - m_log.DebugFormat( - "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", - sp.Name, m_scene.RegionInfo.RegionName); - foreach (int i in Enum.GetValues(typeof(BakeType))) { BakeType bakeType = (BakeType)i; @@ -283,7 +290,31 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); - Primitive.TextureEntryFace bakedTextureFace = faceTextures[ftIndex]; + bakedTextures[bakeType] = faceTextures[ftIndex]; + } + + return bakedTextures; + } + + public bool SaveBakedTextures(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + + if (sp == null) + return false; + + m_log.DebugFormat( + "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", + sp.Name, m_scene.RegionInfo.RegionName); + + Dictionary bakedTextures = GetBakedTextureFaces(sp); + + if (bakedTextures.Count == 0) + return false; + + foreach (BakeType bakeType in bakedTextures.Keys) + { + Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType]; if (bakedTextureFace == null) { @@ -299,6 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (asset != null) { asset.Temporary = false; + asset.Local = false; m_scene.AssetService.Store(asset); } else diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index b831b31..7b2f14e 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -26,9 +26,12 @@ */ using System; +using System.Collections.Generic; +using Nini.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.CoreModules.Asset; using OpenSim.Region.Framework.Scenes; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -65,5 +68,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // TODO: Check baked texture Assert.AreEqual(visualParams, sp.Appearance.VisualParams); } + + [Test] + public void TestSaveBakedTextures() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID userId = TestHelpers.ParseTail(0x1); + UUID eyesTextureId = TestHelpers.ParseTail(0x2); + + // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly + // to the AssetService, which will then store temporary and local assets permanently + CoreAssetCache assetCache = new CoreAssetCache(); + + AvatarFactoryModule afm = new AvatarFactoryModule(); + TestScene scene = SceneHelpers.SetupScene(assetCache); + SceneHelpers.SetupSceneModules(scene, afm); + IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; + + // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules + AssetBase uploadedAsset; + uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString()); + uploadedAsset.Data = new byte[] { 2 }; + uploadedAsset.Temporary = true; + uploadedAsset.Local = true; // Local assets aren't persisted, non-local are + scene.AssetService.Store(uploadedAsset); + + byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; + for (byte i = 0; i < visualParams.Length; i++) + visualParams[i] = i; + + Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)); + uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes); + Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); + eyesFace.TextureID = eyesTextureId; + + afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams); + afm.SaveBakedTextures(userId); +// Dictionary bakedTextures = afm.GetBakedTextureFaces(userId); + + // We should also inpsect the asset data store layer directly, but this is difficult to get at right now. + assetCache.Clear(); + + AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString()); + Assert.That(eyesBake, Is.Not.Null); + Assert.That(eyesBake.Temporary, Is.False); + Assert.That(eyesBake.Local, Is.False); + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 51d1d59..cc5d061 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs @@ -129,15 +129,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset m_Cache = null; } - m_log.InfoFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); + m_log.DebugFormat( + "[LOCAL ASSET SERVICES CONNECTOR]: Enabled connector for region {0}", scene.RegionInfo.RegionName); if (m_Cache != null) { - m_log.InfoFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); + m_log.DebugFormat( + "[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}", + scene.RegionInfo.RegionName); } else { - // Short-circuit directly to storage layer + // Short-circuit directly to storage layer. This ends up storing temporary and local assets. // scene.UnregisterModuleInterface(this); scene.RegisterModuleInterface(m_AssetService); @@ -246,9 +249,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset m_Cache.Cache(asset); if (asset.Temporary || asset.Local) + { +// m_log.DebugFormat( +// "[LOCAL ASSET SERVICE CONNECTOR]: Returning asset {0} {1} without querying database since status Temporary = {2}, Local = {3}", +// asset.Name, asset.ID, asset.Temporary, asset.Local); + return asset.ID; - - return m_AssetService.Store(asset); + } + else + { +// m_log.DebugFormat( +// "[LOCAL ASSET SERVICE CONNECTOR]: Passing {0} {1} on to asset service for storage, status Temporary = {2}, Local = {3}", +// asset.Name, asset.ID, asset.Temporary, asset.Local); + + return m_AssetService.Store(asset); + } } public bool UpdateContent(string id, byte[] data) diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs index 6817725..4dbddf4 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; @@ -39,7 +40,23 @@ namespace OpenSim.Region.Framework.Interfaces /// bool SendAppearance(UUID agentId); + /// + /// Return the baked texture ids of the given agent. + /// + /// + /// An empty list if this agent has no baked textures (e.g. because it's a child agent) + Dictionary GetBakedTextureFaces(UUID agentId); + + /// + /// Save the baked textures for the given agent permanently in the asset database. + /// + /// + /// This is used to preserve apperance textures for NPCs + /// + /// + /// true if a valid agent was found, false otherwise bool SaveBakedTextures(UUID agentId); + bool ValidateBakedTextureCache(IClientAPI client); void QueueAppearanceSend(UUID agentid); void QueueAppearanceSave(UUID agentid); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4148d4b..4143d44 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1695,9 +1695,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void MoveToTarget(Vector3 pos, bool noFly) { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", -// Name, pos, m_scene.RegionInfo.RegionName); + m_log.DebugFormat( + "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", + Name, pos, m_scene.RegionInfo.RegionName); if (pos.X < 0 || pos.X >= Constants.RegionSize || pos.Y < 0 || pos.Y >= Constants.RegionSize -- cgit v1.1 From e7a515bab0e46c228f8f543397f97b7ba2f0df3c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 22:06:24 +0100 Subject: Fix bug where attachments were remaining on the avatar after being dropped. If the inventory service is configured not to allow deletion then these will not disappear from inventory --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 12 ++++++++++-- .../Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 14 ++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2d5eb18..b7a7f77 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -451,6 +451,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void DetachSingleAttachmentToGround(UUID sceneObjectID, IClientAPI remoteClient) { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", +// remoteClient.Name, sceneObjectID); + SceneObjectGroup so = m_scene.GetSceneObjectGroup(sceneObjectID); if (so == null) @@ -461,6 +465,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments UUID inventoryID = so.GetFromItemID(); +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", +// so.Name, so.LocalId, inventoryID); + ScenePresence presence; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { @@ -468,7 +476,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) return; - bool changed = presence.Appearance.DetachAttachment(sceneObjectID); + bool changed = presence.Appearance.DetachAttachment(inventoryID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); @@ -485,7 +493,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } /// - /// Detach the given scene objet to the ground. + /// Detach the given scene object to the ground. /// /// /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc. diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index bb53601..b1f9197 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -138,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - // Check status on scene presence + // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.True); List attachments = m_presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(1)); @@ -149,12 +149,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); - // Check item status + // Check appearance status Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] - public void TestDetachAttachmentToScene() + public void TestDetachAttachmentToGround() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); @@ -168,15 +168,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UserInventoryHelpers.CreateInventoryItem( scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); +// Check item status + Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Not.Null); + UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); m_attMod.DetachSingleAttachmentToGround(attSoId, m_presence.ControllingClient); - // Check status on scene presence + // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.False); List attachments = m_presence.Attachments; Assert.That(attachments.Count, Is.EqualTo(0)); + // Check appearance status + Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0)); + // Check item status Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null); -- cgit v1.1 From 1de68b34d959570c6dc5de42e8dac5e36f960273 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 22:25:38 +0100 Subject: refactor: migrate DropObject handling fully into AttachmentsModule from Scene --- .../Avatar/Attachments/AttachmentsModule.cs | 21 ++++++++++----------- .../Attachments/Tests/AttachmentsModuleTests.cs | 7 ++----- .../Framework/Interfaces/IAttachmentsModule.cs | 8 ++++---- OpenSim/Region/Framework/Scenes/Scene.cs | 2 -- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 7 ------- 5 files changed, 16 insertions(+), 29 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b7a7f77..02fd387 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -46,7 +46,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene = null; + private Scene m_scene; private IDialogModule m_dialogModule; public string Name { get { return "Attachments Module"; } } @@ -83,6 +83,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments client.OnObjectAttach += AttachObject; client.OnObjectDetach += DetachObject; client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv; + client.OnObjectDrop += DetachSingleAttachmentToGround; } public void UnsubscribeFromClientEvents(IClientAPI client) @@ -92,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments client.OnObjectAttach -= AttachObject; client.OnObjectDetach -= DetachObject; client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv; + client.OnObjectDrop -= DetachSingleAttachmentToGround; } /// @@ -250,12 +252,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); } - public UUID RezSingleAttachmentFromInventory( + public ISceneEntity RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) { // m_log.DebugFormat( @@ -269,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); - return UUID.Zero; + return null; } // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -286,10 +288,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ShowAttachInUserInventory(att, sp, itemID, AttachmentPt); } - if (null == att) - return UUID.Zero; - else - return att.UUID; + return att; } private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( @@ -449,13 +448,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public void DetachSingleAttachmentToGround(UUID sceneObjectID, IClientAPI remoteClient) + public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", // remoteClient.Name, sceneObjectID); - SceneObjectGroup so = m_scene.GetSceneObjectGroup(sceneObjectID); + SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); if (so == null) return; @@ -489,7 +488,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments remoteClient.SendRemoveInventoryItem(inventoryID); } - m_scene.EventManager.TriggerOnAttach(so.LocalId, sceneObjectID, UUID.Zero); + m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b1f9197..b0146a1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -168,12 +168,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UserInventoryHelpers.CreateInventoryItem( scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); -// Check item status - Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Not.Null); - - UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( + ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToGround(attSoId, m_presence.ControllingClient); + m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.False); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 86f5a0f..c910289 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// The scene object that was attached. Null if the scene object could not be found - UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); + ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); /// /// Rez an attachment from user inventory @@ -77,7 +77,7 @@ namespace OpenSim.Region.Framework.Interfaces /// False is required so that we don't attempt to update information when a user enters a scene with the /// attachment already correctly set up in inventory. /// The uuid of the scene object that was attached. Null if the scene object could not be found - UUID RezSingleAttachmentFromInventory( + ISceneEntity RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus); /// @@ -105,9 +105,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Detach the given item to the ground. /// - /// + /// /// - void DetachSingleAttachmentToGround(UUID sceneObjectID, IClientAPI remoteClient); + void DetachSingleAttachmentToGround(uint objectLocalID, IClientAPI remoteClient); /// /// Detach the given item so that it remains in the user's inventory. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 45d1a0e..e0250de 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2772,7 +2772,6 @@ namespace OpenSim.Region.Framework.Scenes client.OnUndo += m_sceneGraph.HandleUndo; client.OnRedo += m_sceneGraph.HandleRedo; client.OnObjectDescription += m_sceneGraph.PrimDescription; - client.OnObjectDrop += m_sceneGraph.DropObject; client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable; client.OnObjectOwner += ObjectOwner; } @@ -2899,7 +2898,6 @@ namespace OpenSim.Region.Framework.Scenes client.OnUndo -= m_sceneGraph.HandleUndo; client.OnRedo -= m_sceneGraph.HandleRedo; client.OnObjectDescription -= m_sceneGraph.PrimDescription; - client.OnObjectDrop -= m_sceneGraph.DropObject; client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable; client.OnObjectOwner -= ObjectOwner; } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 0582586..76ed55c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -548,13 +548,6 @@ namespace OpenSim.Region.Framework.Scenes m_activeScripts += number; } - public void DropObject(uint objectLocalID, IClientAPI remoteClient) - { - SceneObjectGroup group = GetGroupByPrim(objectLocalID); - if (group != null) - m_parentScene.AttachmentsModule.DetachSingleAttachmentToGround(group.UUID, remoteClient); - } - protected internal void HandleUndo(IClientAPI remoteClient, UUID primId) { if (primId != UUID.Zero) -- cgit v1.1 From a90e1cf3aa6ae832e1ff4f2683e1c991eb9a849f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 22:39:16 +0100 Subject: add Name property to ISceneEntity --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c453366..74e8783 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -254,11 +254,14 @@ namespace OpenSim.Region.Framework.Scenes /// public override string Name { - get { + get + { if (RootPart == null) return String.Empty; - return RootPart.Name; + else + return RootPart.Name; } + set { RootPart.Name = value; } } -- cgit v1.1 From 04bafd21221a789b83b039efd1c52e141944cde0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 23:05:43 +0100 Subject: refactor: Move ScenePresence.RezAttachments() into AttachmentsModule This adds an incomplete IScenePresence to match ISceneEntity --- .../Avatar/Attachments/AttachmentsModule.cs | 38 +++++++++++++++ .../Framework/Interfaces/IAttachmentsModule.cs | 6 +++ .../Region/Framework/Interfaces/IScenePresence.cs | 56 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 46 +----------------- .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- 6 files changed, 103 insertions(+), 47 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IScenePresence.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 02fd387..f6aea89 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -95,6 +95,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv; client.OnObjectDrop -= DetachSingleAttachmentToGround; } + + /// + /// RezAttachments. This should only be called upon login on the first region. + /// Attachment rezzings on crossings and TPs are done in a different way. + /// + public void RezAttachments(IScenePresence sp) + { + if (null == sp.Appearance) + { + m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); + return; + } + + List attachments = sp.Appearance.GetAttachments(); + foreach (AvatarAttachment attach in attachments) + { + int p = attach.AttachPoint; + UUID itemID = attach.ItemID; + + //UUID assetID = attach.AssetID; + // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down + // But they're not used anyway, the item is being looked up for now, so let's proceed. + //if (UUID.Zero == assetID) + //{ + // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); + // continue; + //} + + try + { + RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, (uint)p); + } + catch (Exception e) + { + m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); + } + } + } /// /// Called by client diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index c910289..1833dce 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -36,6 +36,12 @@ namespace OpenSim.Region.Framework.Interfaces public interface IAttachmentsModule { /// + /// RezAttachments. This should only be called upon login on the first region. + /// Attachment rezzings on crossings and TPs are done in a different way. + /// + void RezAttachments(IScenePresence sp); + + /// /// Attach an object to an avatar from the world. /// /// diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs new file mode 100644 index 0000000..d700d79 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -0,0 +1,56 @@ +/* + * 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 OpenSim.Framework; + +namespace OpenSim.Region.Framework.Interfaces +{ + /// + /// An agent in the scene. + /// + /// + /// Interface is a work in progress. Please feel free to add other required properties and methods. + /// + public interface IScenePresence : ISceneEntity + { + /// + /// The client controlling this presence + /// + IClientAPI ControllingClient { get; } + + /// + /// Avatar appearance data. + /// + /// + // Because appearance setting is in a module, we actually need + // to give it access to our appearance directly, otherwise we + // get a synchronization issue. + /// + AvatarAppearance Appearance { get; set; } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e0250de..e7fe8df 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2578,7 +2578,7 @@ namespace OpenSim.Region.Framework.Scenes if (aCircuit.child == false) { sp.IsChildAgent = false; - Util.FireAndForget(delegate(object o) { sp.RezAttachments(); }); + Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4143d44..040e801 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List coarseLocations, List avatarUUIDs); - public class ScenePresence : EntityBase, ISceneEntity + public class ScenePresence : EntityBase, IScenePresence { // ~ScenePresence() // { @@ -444,9 +444,6 @@ namespace OpenSim.Region.Framework.Scenes protected PhysicsActor m_physicsActor; - /// - /// The client controlling this presence - /// public IClientAPI ControllingClient { get { return m_controllingClient; } @@ -2689,9 +2686,6 @@ namespace OpenSim.Region.Framework.Scenes UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); } - // Because appearance setting is in a module, we actually need - // to give it access to our appearance directly, otherwise we - // get a synchronization issue. public AvatarAppearance Appearance { get { return m_appearance; } @@ -3813,44 +3807,6 @@ namespace OpenSim.Region.Framework.Scenes return flags; } - /// - /// RezAttachments. This should only be called upon login on the first region. - /// Attachment rezzings on crossings and TPs are done in a different way. - /// - public void RezAttachments() - { - if (null == m_appearance) - { - m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); - return; - } - - List attachments = m_appearance.GetAttachments(); - foreach (AvatarAttachment attach in attachments) - { - int p = attach.AttachPoint; - UUID itemID = attach.ItemID; - - //UUID assetID = attach.AssetID; - // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down - // But they're not used anyway, the item is being looked up for now, so let's proceed. - //if (UUID.Zero == assetID) - //{ - // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); - // continue; - //} - - try - { - m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); - } - catch (Exception e) - { - m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); - } - } - } - private void ReprioritizeUpdates() { if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index c1da803..79c79e4 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -155,7 +155,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); sp.Appearance = npcAppearance; - sp.RezAttachments(); + scene.AttachmentsModule.RezAttachments(sp); IAvatarFactory module = scene.RequestModuleInterface(); module.SendAppearance(sp.UUID); -- cgit v1.1 From ddc733cd3d940a4357eb0d235562050eb6f206bf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 23:32:30 +0100 Subject: refactor: move SP.SaveChangedAttachments() fully into AttachmentsModule --- .../Avatar/Attachments/AttachmentsModule.cs | 18 ++++++++++++++++ .../Framework/Interfaces/IAttachmentsModule.cs | 6 ++++++ .../Region/Framework/Interfaces/IScenePresence.cs | 11 ++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 25 +--------------------- 5 files changed, 38 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f6aea89..201ce7f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -133,6 +133,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } } + + public void SaveChangedAttachments(IScenePresence sp) + { + // Need to copy this list because DetachToInventoryPrep mods it + List attachments = new List(sp.Attachments.ToArray()); + + foreach (SceneObjectGroup grp in attachments) + { + if (grp.HasGroupChanged) // Resizer scripts? + { + grp.IsAttachment = false; + grp.AbsolutePosition = grp.RootPart.AttachedPos; +// grp.DetachToInventoryPrep(); + UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); + grp.IsAttachment = true; + } + } + } /// /// Called by client diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 1833dce..ce795f1 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -42,6 +42,12 @@ namespace OpenSim.Region.Framework.Interfaces void RezAttachments(IScenePresence sp); /// + /// Save the attachments that have change on this presence. + /// + /// + void SaveChangedAttachments(IScenePresence sp); + + /// /// Attach an object to an avatar from the world. /// /// diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index d700d79..b07c821 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -26,7 +26,9 @@ */ using System; +using System.Collections.Generic; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces { @@ -52,5 +54,14 @@ namespace OpenSim.Region.Framework.Interfaces // get a synchronization issue. /// AvatarAppearance Appearance { get; set; } + + /// + /// The scene objects attached to this avatar. + /// + /// + /// Do not change this list directly - use methods such as + /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. + /// + List Attachments { get; } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e7fe8df..e0e3884 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3162,8 +3162,8 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnRemovePresence(agentID); - if (avatar != null && (!avatar.IsChildAgent) && avatar.PresenceType != PresenceType.Npc) - avatar.SaveChangedAttachments(); + if (AttachmentsModule != null && avatar != null && (!avatar.IsChildAgent) && avatar.PresenceType != PresenceType.Npc) + AttachmentsModule.SaveChangedAttachments(avatar); ForEachClient( delegate(IClientAPI client) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 040e801..91e11eb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3831,28 +3831,5 @@ namespace OpenSim.Region.Framework.Scenes m_reprioritization_called = false; } } - - public void SaveChangedAttachments() - { - // Need to copy this list because DetachToInventoryPrep mods it - List attachments = new List(Attachments.ToArray()); - - IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule; - if (attachmentsModule != null) - { - foreach (SceneObjectGroup grp in attachments) - { - if (grp.HasGroupChanged) // Resizer scripts? - { - grp.IsAttachment = false; - grp.AbsolutePosition = grp.RootPart.AttachedPos; -// grp.DetachToInventoryPrep(); - attachmentsModule.UpdateKnownItem(ControllingClient, - grp, grp.GetFromItemID(), grp.OwnerID); - grp.IsAttachment = true; - } - } - } - } } -} +} \ No newline at end of file -- cgit v1.1 From 1809aaf74c3594ec40df8688a2dcc42074ddeec4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 23:36:45 +0100 Subject: minor: remove already processed avatar null check in Scene.RemoveClient() remove some now duplicated method doc --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 1 - OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ---- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 201ce7f..e2f6a9e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -145,7 +145,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { grp.IsAttachment = false; grp.AbsolutePosition = grp.RootPart.AttachedPos; -// grp.DetachToInventoryPrep(); UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); grp.IsAttachment = true; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e0e3884..9368285 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3162,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnRemovePresence(agentID); - if (AttachmentsModule != null && avatar != null && (!avatar.IsChildAgent) && avatar.PresenceType != PresenceType.Npc) + if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) AttachmentsModule.SaveChangedAttachments(avatar); ForEachClient( diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 91e11eb..0a91989 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -114,10 +114,6 @@ namespace OpenSim.Region.Framework.Scenes } protected ScenePresenceAnimator m_animator; - /// - /// The scene objects attached to this avatar. Do not change this list directly - use methods such as - /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. - /// public List Attachments { get { return m_attachments; } -- cgit v1.1 From 2acfff9f6d340984bbc51c4d18c2babe2e3cb6ca Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 30 Aug 2011 23:39:26 +0100 Subject: remove pointless ToArray() call in AttachmentsModule.SaveChangedAttachments() --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index e2f6a9e..f4bc495 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -137,7 +137,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void SaveChangedAttachments(IScenePresence sp) { // Need to copy this list because DetachToInventoryPrep mods it - List attachments = new List(sp.Attachments.ToArray()); + List attachments = new List(sp.Attachments); foreach (SceneObjectGroup grp in attachments) { -- cgit v1.1 From 32444d98cb13423fdf8c874e4fbb7ea17670d7c5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 16:29:51 +0100 Subject: Make SP.Attachments available as sp.GetAttachments() instead. The approach here, as in other parts of OpenSim, is to return a copy of the list rather than the attachments list itself This prevents callers from forgetting to lock the list when they read it, as was happening in various parts of the codebase. It also improves liveness. This might improve attachment anomolies when performing region crossings. --- .../Avatar/Attachments/AttachmentsModule.cs | 19 +++---- .../Attachments/Tests/AttachmentsModuleTests.cs | 10 ++-- .../EntityTransfer/EntityTransferModule.cs | 61 ++++++++++++---------- .../Scripting/WorldComm/WorldCommModule.cs | 12 +++-- .../Region/Framework/Interfaces/IScenePresence.cs | 7 ++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 51 +++++++++++++----- .../Region/OptionalModules/World/NPC/NPCModule.cs | 10 ++-- 7 files changed, 98 insertions(+), 72 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f4bc495..9e5ce8f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -136,10 +136,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void SaveChangedAttachments(IScenePresence sp) { - // Need to copy this list because DetachToInventoryPrep mods it - List attachments = new List(sp.Attachments); - - foreach (SceneObjectGroup grp in attachments) + foreach (SceneObjectGroup grp in sp.GetAttachments()) { if (grp.HasGroupChanged) // Resizer scripts? { @@ -273,14 +270,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove any previous attachments UUID itemID = UUID.Zero; - foreach (SceneObjectGroup grp in sp.Attachments) - { - if (grp.AttachmentPoint == attachmentPt) - { - itemID = grp.GetFromItemID(); - break; - } - } + + List attachments = sp.GetAttachments(attachmentPt); + + // At the moment we can only deal with a single attachment + if (attachments.Count != 0) + itemID = attachments[0].GetFromItemID(); if (itemID != UUID.Zero) DetachSingleAttachmentToInv(itemID, sp); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b0146a1..363e258 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.True); - List attachments = m_presence.Attachments; + List attachments = m_presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); @@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.True); - List attachments = m_presence.Attachments; + List attachments = m_presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); @@ -174,7 +174,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.False); - List attachments = m_presence.Attachments; + List attachments = m_presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(0)); // Check appearance status @@ -208,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.False); - List attachments = m_presence.Attachments; + List attachments = m_presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(0)); // Check item status @@ -237,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); Assert.That(presence.HasAttachments(), Is.True); - List attachments = presence.Attachments; + List attachments = presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7963e53..c24cc17 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -208,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Teleport(position); - foreach (SceneObjectGroup grp in sp.Attachments) + foreach (SceneObjectGroup grp in sp.GetAttachments()) sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } else // Another region possibly in another simulator @@ -559,11 +559,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) { - foreach (SceneObjectGroup sop in sp.Attachments) + foreach (SceneObjectGroup sop in sp.GetAttachments()) { sop.Scene.DeleteSceneObject(sop, true); } - sp.Attachments.Clear(); + sp.ClearAttachments(); } protected void KillEntity(Scene scene, uint localID) @@ -1764,34 +1764,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) { - List m_attachments = sp.Attachments; - lock (m_attachments) + List m_attachments = sp.GetAttachments(); + + // Validate + foreach (SceneObjectGroup gobj in m_attachments) { - // Validate - foreach (SceneObjectGroup gobj in m_attachments) - { - if (gobj == null || gobj.IsDeleted) - return false; - } + if (gobj == null || gobj.IsDeleted) + return false; + } - foreach (SceneObjectGroup gobj in m_attachments) + foreach (SceneObjectGroup gobj in m_attachments) + { + // If the prim group is null then something must have happened to it! + if (gobj != null && gobj.RootPart != null) { - // If the prim group is null then something must have happened to it! - if (gobj != null && gobj.RootPart != null) - { - // Set the parent localID to 0 so it transfers over properly. - gobj.RootPart.SetParentLocalId(0); - gobj.AbsolutePosition = gobj.RootPart.AttachedPos; - gobj.IsAttachment = false; - //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); - CrossPrimGroupIntoNewRegion(destination, gobj, silent); - } + // Set the parent localID to 0 so it transfers over properly. + gobj.RootPart.SetParentLocalId(0); + gobj.AbsolutePosition = gobj.RootPart.AttachedPos; + gobj.IsAttachment = false; + //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); + CrossPrimGroupIntoNewRegion(destination, gobj, silent); } - m_attachments.Clear(); - - return true; } + + sp.ClearAttachments(); + + return true; } #endregion @@ -1840,7 +1839,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer int i = 0; if (sp.InTransitScriptStates.Count > 0) { - sp.Attachments.ForEach(delegate(SceneObjectGroup sog) + List attachments = sp.GetAttachments(); + + foreach (SceneObjectGroup sog in attachments) { if (i < sp.InTransitScriptStates.Count) { @@ -1849,8 +1850,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sog.ResumeScripts(); } else - m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", sp.InTransitScriptStates.Count, sp.Attachments.Count); - }); + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", + sp.InTransitScriptStates.Count, attachments.Count); + } sp.InTransitScriptStates.Clear(); } diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 22352f5..057500c 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -283,7 +283,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } /// - /// Delivers the message to. + /// Delivers the message to a scene entity. /// /// /// Target. @@ -314,17 +314,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false); } - List attachments = sp.Attachments; + List attachments = sp.GetAttachments(); + // Nothing left to do if (attachments == null) return true; // Get uuid of attachments List targets = new List(); - foreach ( SceneObjectGroup sog in attachments ) + foreach (SceneObjectGroup sog in attachments) { targets.Add(sog.UUID); } + // Need to check each attachment foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) { @@ -334,9 +336,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) continue; - if ( targets.Contains(li.GetHostID())) + if (targets.Contains(li.GetHostID())) QueueMessage(new ListenerInfo(li, name, id, msg)); } + return true; } @@ -363,6 +366,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm break; } } + return true; } diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index b07c821..788b36f 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -58,10 +58,13 @@ namespace OpenSim.Region.Framework.Interfaces /// /// The scene objects attached to this avatar. /// + /// + /// A copy of the list. + /// /// /// Do not change this list directly - use methods such as - /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. + /// AddAttachment() and RemoveAttachment(). /// - List Attachments { get; } + List GetAttachments(); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0a91989..f5c72e1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -114,10 +114,13 @@ namespace OpenSim.Region.Framework.Scenes } protected ScenePresenceAnimator m_animator; - public List Attachments - { - get { return m_attachments; } - } + /// + /// Attachments recorded on this avatar. + /// + /// + /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is + /// necessary. + /// protected List m_attachments = new List(); private Dictionary scriptedcontrols = new Dictionary(); @@ -940,15 +943,18 @@ namespace OpenSim.Region.Framework.Scenes // and it has already rezzed the attachments and started their scripts. // We do the following only for non-login agents, because their scripts // haven't started yet. - if (wasChild && Attachments != null && Attachments.Count > 0) + lock (m_attachments) { - m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); - // Resume scripts - Attachments.ForEach(delegate(SceneObjectGroup sog) + if (wasChild && m_attachments != null && m_attachments.Count > 0) { - sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); - sog.ResumeScripts(); - }); + m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); + // Resume scripts + foreach (SceneObjectGroup sog in m_attachments) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + } + } } // send the animations of the other presences to me @@ -3472,9 +3478,19 @@ namespace OpenSim.Region.Framework.Scenes m_attachments.Add(gobj); } } - + /// - /// Get the scene object attached to the given point. + /// Get all the presence's attachments. + /// + /// A copy of the list which contains the attachments. + public List GetAttachments() + { + lock (m_attachments) + return new List(m_attachments); + } + + /// + /// Get the scene objects attached to the given point. /// /// /// Returns an empty list if there were no attachments at the point. @@ -3521,6 +3537,15 @@ namespace OpenSim.Region.Framework.Scenes m_attachments.Remove(gobj); } + /// + /// Clear all attachments + /// + public void ClearAttachments() + { + lock (m_attachments) + m_attachments.Clear(); + } + public bool ValidateAttachments() { lock (m_attachments) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 79c79e4..e58dca2 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -144,14 +144,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC return false; // FIXME: An extremely bad bit of code that reaches directly into the attachments list and manipulates it - List attachments = sp.Attachments; - lock (attachments) - { - foreach (SceneObjectGroup att in attachments) - scene.DeleteSceneObject(att, false); + foreach (SceneObjectGroup att in sp.GetAttachments()) + scene.DeleteSceneObject(att, false); - attachments.Clear(); - } + sp.ClearAttachments(); AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); sp.Appearance = npcAppearance; -- cgit v1.1 From 5a5206449f575fa4c6e161aea7202b7b8f628b4a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 16:41:58 +0100 Subject: minor: seal up another instance of using the appearance list without locking --- OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 057500c..f25699b 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -366,7 +366,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm break; } } - + return true; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f5c72e1..e3b7c72 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3512,7 +3512,8 @@ namespace OpenSim.Region.Framework.Scenes public bool HasAttachments() { - return m_attachments.Count > 0; + lock (m_attachments) + return m_attachments.Count > 0; } public bool HasScriptedAttachments() -- cgit v1.1 From 54839d28ad0bf2a2e613dd698e8927823ed64349 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 16:46:43 +0100 Subject: remove pointless m_attachments == null check since this field is never null --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e3b7c72..43a845c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -945,7 +945,7 @@ namespace OpenSim.Region.Framework.Scenes // haven't started yet. lock (m_attachments) { - if (wasChild && m_attachments != null && m_attachments.Count > 0) + if (wasChild && HasAttachments()) { m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); // Resume scripts -- cgit v1.1 From 8c703022c14c55df6e862c6462ec8c7c39917296 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 16:50:18 +0100 Subject: In WorldCommModule, replace the useless Attachments == null check with Attachments.Count == 0 instead --- OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index f25699b..b20a875 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -316,8 +316,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm List attachments = sp.GetAttachments(); - // Nothing left to do - if (attachments == null) + if (attachments.Count == 0) return true; // Get uuid of attachments -- cgit v1.1 From 899d109e822bbf6084714842b460858f3939840b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 17:13:53 +0100 Subject: get rid of appearance null checks - this is never null --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 50 +++++++--------------- .../Scenes/Tests/ScenePresenceAgentTests.cs | 1 + 2 files changed, 16 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 43a845c..cda2006 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -885,11 +885,8 @@ namespace OpenSim.Region.Framework.Scenes } float localAVHeight = 1.56f; - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - localAVHeight = m_appearance.AvatarHeight; - } + if (m_appearance.AvatarHeight > 0) + localAVHeight = m_appearance.AvatarHeight; float posZLimit = 0; @@ -903,25 +900,10 @@ namespace OpenSim.Region.Framework.Scenes } AbsolutePosition = pos; - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - else - { - m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); - // emergency; this really shouldn't happen - m_appearance = new AvatarAppearance(); - } - - AddToPhysicalScene(isFlying); + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } + AddToPhysicalScene(isFlying); if (m_forceFly) { @@ -1053,11 +1035,10 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; AbsolutePosition = pos; AddToPhysicalScene(isFlying); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } + + // FIXME: Move me into AddToPhysicalScene + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); SendTerseUpdateToAllClients(); } @@ -1071,11 +1052,9 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); AbsolutePosition = pos; AddToPhysicalScene(isFlying); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } + + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); SendTerseUpdateToAllClients(); } @@ -1129,7 +1108,7 @@ namespace OpenSim.Region.Framework.Scenes #region Event Handlers /// - /// Sets avatar height in the phyiscs plugin + /// Sets avatar height in the physics plugin /// public void SetHeight(float height) { @@ -1846,7 +1825,8 @@ namespace OpenSim.Region.Framework.Scenes m_parentID = 0; SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; - if (m_physicsActor != null && m_appearance != null) + + if (m_physicsActor != null) { if (m_appearance.AvatarHeight > 0) SetHeight(m_appearance.AvatarHeight); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 35b41fb..ce9d418 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -357,6 +357,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests agent.InventoryFolder = UUID.Zero; agent.startpos = Vector3.Zero; agent.CapsPath = GetRandomCapsObjectPath(); + agent.Appearance = new AvatarAppearance(); acd1 = agent; } -- cgit v1.1 From e69f246b861c824149d8b4e7cc4ff7899d5318db Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 17:25:18 +0100 Subject: refactor: move multiple class to set avatar height into associated SP.AddToPhysicalScene() --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 ++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index f34b6d2..b6a1564 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -214,7 +214,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory changed = sp.Appearance.SetVisualParams(visualParams); if (sp.Appearance.AvatarHeight > 0) sp.SetHeight(sp.Appearance.AvatarHeight); - } + } // Process the baked texture array if (textureEntry != null) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cda2006..5e96b0a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -900,9 +900,6 @@ namespace OpenSim.Region.Framework.Scenes } AbsolutePosition = pos; - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - AddToPhysicalScene(isFlying); if (m_forceFly) @@ -1036,10 +1033,6 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; AddToPhysicalScene(isFlying); - // FIXME: Move me into AddToPhysicalScene - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - SendTerseUpdateToAllClients(); } @@ -1053,9 +1046,6 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; AddToPhysicalScene(isFlying); - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - SendTerseUpdateToAllClients(); } @@ -1825,12 +1815,6 @@ namespace OpenSim.Region.Framework.Scenes m_parentID = 0; SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; - - if (m_physicsActor != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } } Animator.TrySetMovementAnimation("STAND"); @@ -3313,6 +3297,8 @@ namespace OpenSim.Region.Framework.Scenes m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong m_physicsActor.SubscribeEvents(500); m_physicsActor.LocalID = LocalId; + + SetHeight(m_appearance.AvatarHeight); } private void OutOfBoundsCall(Vector3 pos) -- cgit v1.1 From 7d58b5fa157b4c3e842573d9fb02a9822034f4b0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 17:53:58 +0100 Subject: move common code into AttachmentsModule.DeleteAttachmentsFromScene() --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 10 ++++++++++ .../Framework/EntityTransfer/EntityTransferModule.cs | 6 +----- .../Region/Framework/Interfaces/IAttachmentsModule.cs | 9 +++++++++ OpenSim/Region/Framework/Interfaces/IScenePresence.cs | 17 +++++++++++++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 14 +------------- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 6 +----- 6 files changed, 37 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 9e5ce8f..587f35e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -147,6 +147,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } } + + public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) + { + foreach (SceneObjectGroup sop in sp.GetAttachments()) + { + sop.Scene.DeleteSceneObject(sop, silent); + } + + sp.ClearAttachments(); + } /// /// Called by client diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index c24cc17..82bdf20 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -559,11 +559,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) { - foreach (SceneObjectGroup sop in sp.GetAttachments()) - { - sop.Scene.DeleteSceneObject(sop, true); - } - sp.ClearAttachments(); + sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); } protected void KillEntity(Scene scene, uint localID) diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index ce795f1..dd11ded 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -48,6 +48,15 @@ namespace OpenSim.Region.Framework.Interfaces void SaveChangedAttachments(IScenePresence sp); /// + /// Delete all the presence's attachments from the scene + /// + /// + /// This is done when a root agent leaves/is demoted to child (for instance, on logout, teleport or region cross). + /// + /// + void DeleteAttachmentsFromScene(IScenePresence sp, bool silent); + + /// /// Attach an object to an avatar from the world. /// /// diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 788b36f..91e4bf2 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -62,9 +62,22 @@ namespace OpenSim.Region.Framework.Interfaces /// A copy of the list. /// /// - /// Do not change this list directly - use methods such as - /// AddAttachment() and RemoveAttachment(). + /// Do not change this list directly - use the attachments module. /// List GetAttachments(); + + /// + /// The scene objects attached to this avatar at a specific attachment point. + /// + /// + /// + List GetAttachments(uint attachmentPoint); + + bool HasAttachments(); + + // Don't use these methods directly. Instead, use the AttachmentsModule + void AddAttachment(SceneObjectGroup gobj); + void RemoveAttachment(SceneObjectGroup gobj); + void ClearAttachments(); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5e96b0a..0d284a5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3401,19 +3401,7 @@ namespace OpenSim.Region.Framework.Scenes public void Close() { - lock (m_attachments) - { - // Delete attachments from scene - // Don't try to save, as this thread won't live long - // enough to complete the save. This would cause no copy - // attachments to poof! - // - foreach (SceneObjectGroup grp in m_attachments) - { - m_scene.DeleteSceneObject(grp, false); - } - m_attachments.Clear(); - } + m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); lock (m_knownChildRegions) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index e58dca2..2fdeeab 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -143,11 +143,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC if (!m_avatars.ContainsKey(agentId)) return false; - // FIXME: An extremely bad bit of code that reaches directly into the attachments list and manipulates it - foreach (SceneObjectGroup att in sp.GetAttachments()) - scene.DeleteSceneObject(att, false); - - sp.ClearAttachments(); + scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); sp.Appearance = npcAppearance; -- cgit v1.1 From ca9a054bba03e58053b4000ec77a6ce6ea492ec6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 18:03:07 +0100 Subject: Don't set a GridUser entry for NPCs. Resolves http://opensimulator.org/mantis/view.php?id=5665 --- .../CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index d6063ad..4cf62ec 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs @@ -66,7 +66,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser public void OnMakeRootAgent(ScenePresence sp) { // m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); - m_GridUserService.SetLastPosition(sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + + if (sp.PresenceType != PresenceType.Npc) + m_GridUserService.SetLastPosition( + sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); } public void OnNewClient(IClientAPI client) -- cgit v1.1 From 083ba72b28fb424e1e3edbc90c6a79d49d2215bf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 23:33:01 +0100 Subject: Fix a bug where the non-root parts of rezzed objects that had previously been attachments were sending their old attachment values to the client. The root part state is the canonical value, so always send that instead. Sending conflicting attachments states for non-root parts of a rezzed object is enough to crash the client. Fixes http://opensimulator.org/mantis/view.php?id=5664. Many thanks to mewtwo0641 for some fantastic qa work on this one. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index dc9a6ed..661e9db 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4761,6 +4761,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP else attachPoint = 0; +// m_log.DebugFormat( +// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", +// attachPoint, part.Name, part.LocalId, Name); + collisionPlane = Vector4.Zero; position = part.RelativePosition; velocity = part.Velocity; @@ -4925,9 +4929,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { update.NameValue = Utils.EmptyBytes; - update.State = data.Shape.State; + + // The root part state is the canonical state for all parts of the object. The other part states in the + // case for attachments may contain conflicting values that can end up crashing the viewer. + update.State = data.ParentGroup.RootPart.Shape.State; } +// m_log.DebugFormat( +// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}", +// update.State, data.Name, data.LocalId, Name); + update.ObjectData = objectData; update.ParentID = data.ParentID; update.PathBegin = data.Shape.PathBegin; -- cgit v1.1 From 095b3e5756bb3160b30c9c5670ba008fa13d2e66 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 01:22:28 +0100 Subject: Remove pointless cluttering SOP.ParentGroup != null checks. The only times when ParentGroup might be null is during regression tests (which might not be a valid thing) and when scene objects are being constructed from the database. At all other times it's not possible for a SOP not to have a SOG parent. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 7 +- .../World/Estate/EstateManagementModule.cs | 50 ++-- .../World/Objects/BuySell/BuySellModule.cs | 5 +- .../World/Permissions/PermissionsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 3 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 49 ++-- OpenSim/Region/Framework/Scenes/Scene.cs | 82 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 29 +-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 282 +++++++++------------ .../Framework/Scenes/SceneObjectPartInventory.cs | 10 +- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 157 ++++-------- .../Shared/Api/Implementation/OSSL_Api.cs | 10 +- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 2 +- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 +- .../Region/ScriptEngine/XEngine/EventManager.cs | 4 +- 16 files changed, 274 insertions(+), 424 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 661e9db..e9ee7be 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4756,10 +4756,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { SceneObjectPart part = (SceneObjectPart)entity; - if (part.ParentGroup != null) - attachPoint = part.ParentGroup.AttachmentPoint; - else - attachPoint = 0; + attachPoint = part.ParentGroup.AttachmentPoint; // m_log.DebugFormat( // "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", @@ -4921,7 +4918,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //update.JointType = 0; update.Material = data.Material; update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim - if (data.ParentGroup != null && data.ParentGroup.IsAttachment) + if (data.ParentGroup.IsAttachment) { update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 3aed6ba..d0605e3 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -851,41 +851,35 @@ namespace OpenSim.Region.CoreModules.World.Estate SceneObjectPart prt = Scene.GetSceneObjectPart(obj); if (prt != null) { - if (prt.ParentGroup != null) + SceneObjectGroup sog = prt.ParentGroup; + LandStatReportItem lsri = new LandStatReportItem(); + lsri.LocationX = sog.AbsolutePosition.X; + lsri.LocationY = sog.AbsolutePosition.Y; + lsri.LocationZ = sog.AbsolutePosition.Z; + lsri.Score = SceneData[obj]; + lsri.TaskID = sog.UUID; + lsri.TaskLocalID = sog.LocalId; + lsri.TaskName = sog.GetPartName(obj); + lsri.OwnerName = "waiting"; + lock (uuidNameLookupList) + uuidNameLookupList.Add(sog.OwnerID); + + if (filter.Length != 0) { - SceneObjectGroup sog = prt.ParentGroup; - if (sog != null) + if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) { - LandStatReportItem lsri = new LandStatReportItem(); - lsri.LocationX = sog.AbsolutePosition.X; - lsri.LocationY = sog.AbsolutePosition.Y; - lsri.LocationZ = sog.AbsolutePosition.Z; - lsri.Score = SceneData[obj]; - lsri.TaskID = sog.UUID; - lsri.TaskLocalID = sog.LocalId; - lsri.TaskName = sog.GetPartName(obj); - lsri.OwnerName = "waiting"; - lock (uuidNameLookupList) - uuidNameLookupList.Add(sog.OwnerID); - - if (filter.Length != 0) - { - if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) - { - } - else - { - continue; - } - } - - SceneReport.Add(lsri); + } + else + { + continue; } } - } + SceneReport.Add(lsri); + } } } + remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); if (uuidNameLookupList.Count > 0) diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index be399ff..8b78701 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice) { SceneObjectPart part = m_scene.GetSceneObjectPart(localID); - if (part == null || part.ParentGroup == null) + if (part == null) return; if (part.ParentGroup.IsDeleted) @@ -111,9 +111,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell if (part == null) return false; - if (part.ParentGroup == null) - return false; - SceneObjectGroup group = part.ParentGroup; switch (saleType) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 7cb3751..b9bd9a4 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1131,7 +1131,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions SceneObjectPart part = scene.GetSceneObjectPart(objectID); if (part.OwnerID != moverID) { - if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) + if (!part.ParentGroup.IsDeleted) { if (part.ParentGroup.IsAttachment) return false; diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 33407ec..1b10e3c 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -208,8 +208,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; - if (group != null) - entityPos = group.AbsolutePosition; + entityPos = group.AbsolutePosition; } // Use the camera position for local agents and avatar position for remote agents diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index addc20c..4700c3b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -225,16 +225,8 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetSceneObjectPart(primId); if (part == null) return new ArrayList(); - SceneObjectGroup group = part.ParentGroup; - if (null == group) - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist", - itemId, primId); - return new ArrayList(); - } + SceneObjectGroup group = part.ParentGroup; // Retrieve item TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId); @@ -971,33 +963,23 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetSceneObjectPart(localID); if (part == null) return; + SceneObjectGroup group = part.ParentGroup; - if (group != null) - { - if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) - return; - - TaskInventoryItem item = group.GetInventoryItem(localID, itemID); - if (item == null) - return; + if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) + return; + + TaskInventoryItem item = group.GetInventoryItem(localID, itemID); + if (item == null) + return; - if (item.Type == 10) - { - part.RemoveScriptEvents(itemID); - EventManager.TriggerRemoveScript(localID, itemID); - } - - group.RemoveInventoryItem(localID, itemID); - part.GetProperties(remoteClient); - } - else + if (item.Type == 10) { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Removal of item {0} requested of prim {1} but this prim does not exist", - itemID, - localID); + part.RemoveScriptEvents(itemID); + EventManager.TriggerRemoveScript(localID, itemID); } + + group.RemoveInventoryItem(localID, itemID); + part.GetProperties(remoteClient); } private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) @@ -1770,7 +1752,7 @@ namespace OpenSim.Region.Framework.Scenes continue; // Already deleted by someone else - if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + if (part.ParentGroup.IsDeleted) continue; // Can't delete child prims @@ -2034,6 +2016,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetSceneObjectPart(localID); if (part == null) continue; + if (!groups.Contains(part.ParentGroup)) groups.Add(part.ParentGroup); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9368285..7f5aea7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3012,58 +3012,51 @@ namespace OpenSim.Region.Framework.Scenes Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z); Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z); - if (target2.ParentGroup != null) - { - pos = target2.AbsolutePosition; - //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); + pos = target2.AbsolutePosition; + //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); - // TODO: Raytrace better here + // TODO: Raytrace better here - //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); - Ray NewRay = new Ray(AXOrigin, AXdirection); + //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); + Ray NewRay = new Ray(AXOrigin, AXdirection); - // Ray Trace against target here - EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); + // Ray Trace against target here + EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); - // Un-comment out the following line to Get Raytrace results printed to the console. - //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); - float ScaleOffset = 0.5f; + // Un-comment out the following line to Get Raytrace results printed to the console. + //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); + float ScaleOffset = 0.5f; - // If we hit something - if (ei.HitTF) + // If we hit something + if (ei.HitTF) + { + Vector3 scale = target.Scale; + Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z); + if (scaleComponent.X != 0) ScaleOffset = scale.X; + if (scaleComponent.Y != 0) ScaleOffset = scale.Y; + if (scaleComponent.Z != 0) ScaleOffset = scale.Z; + ScaleOffset = Math.Abs(ScaleOffset); + Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); + Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z); + Vector3 offset = normal * (ScaleOffset / 2f); + pos = intersectionpoint + offset; + + // stick in offset format from the original prim + pos = pos - target.ParentGroup.AbsolutePosition; + if (CopyRotates) { - Vector3 scale = target.Scale; - Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z); - if (scaleComponent.X != 0) ScaleOffset = scale.X; - if (scaleComponent.Y != 0) ScaleOffset = scale.Y; - if (scaleComponent.Z != 0) ScaleOffset = scale.Z; - ScaleOffset = Math.Abs(ScaleOffset); - Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); - Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z); - Vector3 offset = normal * (ScaleOffset / 2f); - pos = intersectionpoint + offset; - - // stick in offset format from the original prim - pos = pos - target.ParentGroup.AbsolutePosition; - if (CopyRotates) - { - Quaternion worldRot = target2.GetWorldRotation(); + Quaternion worldRot = target2.GetWorldRotation(); - // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); - m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); - //obj.Rotation = worldRot; - //obj.UpdateGroupRotationR(worldRot); - } - else - { - m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID); - } + // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); + m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); + //obj.Rotation = worldRot; + //obj.UpdateGroupRotationR(worldRot); + } + else + { + m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID); } - - return; } - - return; } } @@ -3233,12 +3226,13 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetSceneObjectPart(localID); if (part != null) // It is a prim { - if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid + if (!part.ParentGroup.IsDeleted) // Valid { if (part.ParentGroup.RootPart != part) // Child part return; } } + ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 76ed55c..17a1bcc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1630,27 +1630,18 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup parentGroup = root.ParentGroup; List childGroups = new List(); - if (parentGroup != null) - { - // We do this in reverse to get the link order of the prims correct - for (int i = children.Count - 1; i >= 0; i--) - { - SceneObjectGroup child = children[i].ParentGroup; - if (child != null) - { - // Make sure no child prim is set for sale - // So that, on delink, no prims are unwittingly - // left for sale and sold off - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; - childGroups.Add(child); - } - } - } - else + // We do this in reverse to get the link order of the prims correct + for (int i = children.Count - 1; i >= 0; i--) { - return; // parent is null so not in this region + SceneObjectGroup child = children[i].ParentGroup; + + // Make sure no child prim is set for sale + // So that, on delink, no prims are unwittingly + // left for sale and sold off + child.RootPart.ObjectSaleType = 0; + child.RootPart.SalePrice = 10; + childGroups.Add(child); } foreach (SceneObjectGroup child in childGroups) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 71023a9..4e7504a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -302,7 +302,6 @@ namespace OpenSim.Region.Framework.Scenes protected string m_name; protected Vector3 m_offsetPosition; - // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out. protected SceneObjectGroup m_parentGroup; protected byte[] m_particleSystem = Utils.EmptyBytes; protected ulong m_regionHandle; @@ -592,6 +591,7 @@ namespace OpenSim.Region.Framework.Scenes set { m_passTouches = value; + if (ParentGroup != null) ParentGroup.HasGroupChanged = true; } @@ -759,13 +759,10 @@ namespace OpenSim.Region.Framework.Scenes // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too if (m_sitTargetAvatar != UUID.Zero) { - if (m_parentGroup != null) // TODO can there be a SOP without a SOG? + ScenePresence avatar; + if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar)) { - ScenePresence avatar; - if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar)) - { - avatar.ParentPosition = GetWorldPosition(); - } + avatar.ParentPosition = GetWorldPosition(); } } } @@ -854,7 +851,9 @@ namespace OpenSim.Region.Framework.Scenes actor.Orientation = resultingrotation; //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); } - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); + + if (m_parentGroup != null) + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); //} } catch (Exception ex) @@ -862,7 +861,6 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message); } } - } } @@ -1018,7 +1016,7 @@ namespace OpenSim.Region.Framework.Scenes m_shape.Scale = value; PhysicsActor actor = PhysActor; - if (actor != null && m_parentGroup != null) + if (actor != null) { if (m_parentGroup.Scene != null) { @@ -1059,7 +1057,7 @@ namespace OpenSim.Region.Framework.Scenes set { m_mediaUrl = value; - + if (ParentGroup != null) ParentGroup.HasGroupChanged = true; } @@ -1107,7 +1105,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_sitTargetOrientation = value; } } - public Vector3 SitTargetPosition { get { return m_sitTargetPosition; } @@ -1262,7 +1259,7 @@ namespace OpenSim.Region.Framework.Scenes { get { - if (ParentGroup != null && ParentGroup.Scene != null) + if (ParentGroup.Scene != null) return ParentGroup.Scene.RegionInfo.RegionID; else return UUID.Zero; @@ -1277,14 +1274,13 @@ namespace OpenSim.Region.Framework.Scenes get { if (ParentGroup != null) - { _parentUUID = ParentGroup.UUID; - } + return _parentUUID; } + set { _parentUUID = value; } } - public string SitAnimation { @@ -1514,10 +1510,7 @@ namespace OpenSim.Region.Framework.Scenes impulse = newimpulse; } - if (m_parentGroup != null) - { - m_parentGroup.applyAngularImpulse(impulse); - } + m_parentGroup.applyAngularImpulse(impulse); } /// @@ -1540,10 +1533,7 @@ namespace OpenSim.Region.Framework.Scenes impulse = newimpulse; } - if (m_parentGroup != null) - { - m_parentGroup.setAngularImpulse(impulse); - } + m_parentGroup.setAngularImpulse(impulse); } public Vector3 GetTorque() @@ -1951,8 +1941,6 @@ namespace OpenSim.Region.Framework.Scenes public bool GetDieAtEdge() { - if (m_parentGroup == null) - return false; if (m_parentGroup.IsDeleted) return false; @@ -1961,8 +1949,6 @@ namespace OpenSim.Region.Framework.Scenes public bool GetReturnAtEdge() { - if (m_parentGroup == null) - return false; if (m_parentGroup.IsDeleted) return false; @@ -1971,8 +1957,6 @@ namespace OpenSim.Region.Framework.Scenes public void SetReturnAtEdge(bool p) { - if (m_parentGroup == null) - return; if (m_parentGroup.IsDeleted) return; @@ -1981,8 +1965,6 @@ namespace OpenSim.Region.Framework.Scenes public bool GetBlockGrab() { - if (m_parentGroup == null) - return false; if (m_parentGroup.IsDeleted) return false; @@ -1991,8 +1973,6 @@ namespace OpenSim.Region.Framework.Scenes public void SetBlockGrab(bool p) { - if (m_parentGroup == null) - return; if (m_parentGroup.IsDeleted) return; @@ -2001,8 +1981,6 @@ namespace OpenSim.Region.Framework.Scenes public void SetStatusSandbox(bool p) { - if (m_parentGroup == null) - return; if (m_parentGroup.IsDeleted) return; StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition; @@ -2011,8 +1989,6 @@ namespace OpenSim.Region.Framework.Scenes public bool GetStatusSandbox() { - if (m_parentGroup == null) - return false; if (m_parentGroup.IsDeleted) return false; @@ -2090,11 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes public UUID GetRootPartUUID() { - if (m_parentGroup != null) - { - return m_parentGroup.UUID; - } - return UUID.Zero; + return m_parentGroup.UUID; } /// @@ -2220,8 +2192,6 @@ namespace OpenSim.Region.Framework.Scenes m_lastColliders.Remove(localID); } - if (m_parentGroup == null) - return; if (m_parentGroup.IsDeleted) return; @@ -2242,9 +2212,6 @@ namespace OpenSim.Region.Framework.Scenes { if (localId == 0) continue; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2253,7 +2220,8 @@ namespace OpenSim.Region.Framework.Scenes string data = ""; if (obj != null) { - if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) + if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) + || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); //If it is 1, it is to accept ONLY collisions from this object @@ -2300,7 +2268,8 @@ namespace OpenSim.Region.Framework.Scenes { if (av.LocalId == localId) { - if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) + if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) + || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar @@ -2348,12 +2317,10 @@ namespace OpenSim.Region.Framework.Scenes if (colliding.Count > 0) { StartCollidingMessage.Colliders = colliding; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; + if (m_parentGroup.PassCollision == true) { //TODO: Add pass to root prim! @@ -2374,9 +2341,6 @@ namespace OpenSim.Region.Framework.Scenes // always running this check because if the user deletes the object it would return a null reference. if (localId == 0) continue; - - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2385,7 +2349,8 @@ namespace OpenSim.Region.Framework.Scenes string data = ""; if (obj != null) { - if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) + if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) + || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); //If it is 1, it is to accept ONLY collisions from this object @@ -2432,7 +2397,8 @@ namespace OpenSim.Region.Framework.Scenes { if (av.LocalId == localId) { - if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) + if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) + || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar @@ -2480,9 +2446,6 @@ namespace OpenSim.Region.Framework.Scenes if (colliding.Count > 0) { CollidingMessage.Colliders = colliding; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2503,11 +2466,9 @@ namespace OpenSim.Region.Framework.Scenes if (localId == 0) continue; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; + SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) @@ -2559,7 +2520,8 @@ namespace OpenSim.Region.Framework.Scenes { if (av.LocalId == localId) { - if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) + if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) + || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar @@ -2608,9 +2570,6 @@ namespace OpenSim.Region.Framework.Scenes if (colliding.Count > 0) { EndCollidingMessage.Colliders = colliding; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2619,6 +2578,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) { if (startedColliders.Count > 0) @@ -2646,9 +2606,6 @@ namespace OpenSim.Region.Framework.Scenes if (colliding.Count > 0) { LandStartCollidingMessage.Colliders = colliding; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2657,6 +2614,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) { if (m_lastColliders.Count > 0) @@ -2684,9 +2642,6 @@ namespace OpenSim.Region.Framework.Scenes if (colliding.Count > 0) { LandCollidingMessage.Colliders = colliding; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2695,6 +2650,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) { if (endedColliders.Count > 0) @@ -2722,9 +2678,6 @@ namespace OpenSim.Region.Framework.Scenes if (colliding.Count > 0) { LandEndCollidingMessage.Colliders = colliding; - // always running this check because if the user deletes the object it would return a null reference. - if (m_parentGroup == null) - return; if (m_parentGroup.Scene == null) return; @@ -2748,10 +2701,12 @@ namespace OpenSim.Region.Framework.Scenes { if (PhysActor != null) { - Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); - if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) + if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) + | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) + | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) + | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) { m_parentGroup.AbsolutePosition = newpos; return; @@ -2909,11 +2864,11 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdate() { // m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); - - if (m_parentGroup != null) - { - m_parentGroup.QueueForUpdateCheck(); - } + + if (m_parentGroup == null) + return; + + m_parentGroup.QueueForUpdateCheck(); int timeNow = Util.UnixTimeSinceEpoch(); @@ -2942,13 +2897,14 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleTerseUpdate() { + if (m_parentGroup == null) + return; + if (m_updateFlag < 1) { - if (m_parentGroup != null) - { - m_parentGroup.HasGroupChanged = true; - m_parentGroup.QueueForUpdateCheck(); - } + m_parentGroup.HasGroupChanged = true; + m_parentGroup.QueueForUpdateCheck(); + TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); m_updateFlag = 1; @@ -2960,10 +2916,7 @@ namespace OpenSim.Region.Framework.Scenes public void ScriptSetPhysicsStatus(bool UsePhysics) { - if (m_parentGroup == null) - DoPhysicsPropertyUpdate(UsePhysics, false); - else - m_parentGroup.ScriptSetPhysicsStatus(UsePhysics); + m_parentGroup.ScriptSetPhysicsStatus(UsePhysics); } /// @@ -3003,6 +2956,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) { + if (m_parentGroup == null) + return; + // m_log.DebugFormat( // "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); @@ -3028,6 +2984,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToAllClients() { + if (m_parentGroup == null) + return; + m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); @@ -3040,6 +2999,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToAllClientsExcept(UUID agentID) { + if (m_parentGroup == null) + return; + m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { // Ugly reference :( @@ -3068,6 +3030,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags) { + if (ParentGroup == null) + return; + // Suppress full updates during attachment editing // if (ParentGroup.IsSelected && ParentGroup.IsAttachment) @@ -3250,10 +3215,7 @@ namespace OpenSim.Region.Framework.Scenes public void SetAxisRotation(int axis, int rotate) { - if (m_parentGroup != null) - { - m_parentGroup.SetAxisRotation(axis, rotate); - } + m_parentGroup.SetAxisRotation(axis, rotate); //Cannot use ScriptBaseClass constants as no referance to it currently. if (axis == 2)//STATUS_ROTATE_X @@ -3276,8 +3238,6 @@ namespace OpenSim.Region.Framework.Scenes public void SetDieAtEdge(bool p) { - if (m_parentGroup == null) - return; if (m_parentGroup.IsDeleted) return; @@ -3530,7 +3490,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Set the parent group of this prim. /// public void SetParent(SceneObjectGroup parent) { @@ -3587,8 +3547,11 @@ namespace OpenSim.Region.Framework.Scenes { Text = text; - ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + if (ParentGroup != null) + { + ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } } public void StopLookAt() @@ -3632,7 +3595,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!IgnoreUndoUpdate) { - if (m_parentGroup != null) + if (ParentGroup != null) { lock (m_undo) { @@ -3644,31 +3607,31 @@ namespace OpenSim.Region.Framework.Scenes // TODO: May need to fix for group comparison if (last.Compare(this)) { -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", -// Name, LocalId, m_undo.Count); - + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", + // Name, LocalId, m_undo.Count); + return; } } } - -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", -// Name, LocalId, forGroup, m_undo.Count); - + + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", + // Name, LocalId, forGroup, m_undo.Count); + if (m_parentGroup.GetSceneMaxUndo() > 0) { UndoState nUndo = new UndoState(this, forGroup); - + m_undo.Push(nUndo); - + if (m_redo.Count > 0) m_redo.Clear(); - -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", -// Name, LocalId, forGroup, m_undo.Count); + + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", + // Name, LocalId, forGroup, m_undo.Count); } } } @@ -4245,8 +4208,11 @@ namespace OpenSim.Region.Framework.Scenes } } - ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + if (ParentGroup != null) + { + ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } } public void UpdateGroupPosition(Vector3 pos) @@ -4450,14 +4416,12 @@ namespace OpenSim.Region.Framework.Scenes if (!wasUsingPhysics) { DoPhysicsPropertyUpdate(UsePhysics, false); - if (m_parentGroup != null) + + if (!m_parentGroup.IsDeleted) { - if (!m_parentGroup.IsDeleted) + if (LocalId == m_parentGroup.RootPart.LocalId) { - if (LocalId == m_parentGroup.RootPart.LocalId) - { - m_parentGroup.CheckSculptAndLoad(); - } + m_parentGroup.CheckSculptAndLoad(); } } } @@ -4510,14 +4474,11 @@ namespace OpenSim.Region.Framework.Scenes PhysActor.SetMaterial(Material); DoPhysicsPropertyUpdate(UsePhysics, true); - if (m_parentGroup != null) + if (!m_parentGroup.IsDeleted) { - if (!m_parentGroup.IsDeleted) + if (LocalId == m_parentGroup.RootPart.LocalId) { - if (LocalId == m_parentGroup.RootPart.LocalId) - { - m_parentGroup.CheckSculptAndLoad(); - } + m_parentGroup.CheckSculptAndLoad(); } } @@ -4541,14 +4502,12 @@ namespace OpenSim.Region.Framework.Scenes pa.IsPhysical = UsePhysics; DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim - if (m_parentGroup != null) + + if (!m_parentGroup.IsDeleted) { - if (!m_parentGroup.IsDeleted) + if (LocalId == m_parentGroup.RootPart.LocalId) { - if (LocalId == m_parentGroup.RootPart.LocalId) - { - m_parentGroup.CheckSculptAndLoad(); - } + m_parentGroup.CheckSculptAndLoad(); } } } @@ -4591,8 +4550,11 @@ namespace OpenSim.Region.Framework.Scenes } // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); - ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + if (ParentGroup != null) + { + ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } // m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); } @@ -4605,8 +4567,12 @@ namespace OpenSim.Region.Framework.Scenes (rot.W != RotationOffset.W)) { RotationOffset = rot; - ParentGroup.HasGroupChanged = true; - ScheduleTerseUpdate(); + + if (ParentGroup != null) + { + ParentGroup.HasGroupChanged = true; + ScheduleTerseUpdate(); + } } } @@ -4797,14 +4763,6 @@ namespace OpenSim.Region.Framework.Scenes } } - if (m_parentGroup == null) - { -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId); - ScheduleFullUpdate(); - return; - } - //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) //{ // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; @@ -4830,36 +4788,22 @@ namespace OpenSim.Region.Framework.Scenes public int registerTargetWaypoint(Vector3 target, float tolerance) { - if (m_parentGroup != null) - { - return m_parentGroup.registerTargetWaypoint(target, tolerance); - } - return 0; + return m_parentGroup.registerTargetWaypoint(target, tolerance); } public void unregisterTargetWaypoint(int handle) { - if (m_parentGroup != null) - { - m_parentGroup.unregisterTargetWaypoint(handle); - } + m_parentGroup.unregisterTargetWaypoint(handle); } public int registerRotTargetWaypoint(Quaternion target, float tolerance) { - if (m_parentGroup != null) - { - return m_parentGroup.registerRotTargetWaypoint(target, tolerance); - } - return 0; + return m_parentGroup.registerRotTargetWaypoint(target, tolerance); } public void unregisterRotTargetWaypoint(int handle) { - if (m_parentGroup != null) - { - m_parentGroup.unregisterRotTargetWaypoint(handle); - } + m_parentGroup.unregisterRotTargetWaypoint(handle); } public void SetCameraAtOffset(Vector3 v) @@ -4901,7 +4845,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendTerseUpdateToClient(IClientAPI remoteClient) { - if (ParentGroup == null || ParentGroup.IsDeleted) + if (ParentGroup.IsDeleted) return; if (ParentGroup.IsAttachment && ParentGroup.RootPart != this) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 108089e..e40e57d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -112,15 +112,17 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Reset UUIDs for all the items in the prim's inventory. This involves either generating + /// Reset UUIDs for all the items in the prim's inventory. + /// + /// + /// This involves either generating /// new ones or setting existing UUIDs to the correct parent UUIDs. /// /// If this method is called and there are inventory items, then we regard the inventory as having changed. - /// - /// Link number for the part + /// public void ResetInventoryIDs() { - if (null == m_part || null == m_part.ParentGroup) + if (null == m_part) return; lock (m_items) diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 997845b..e2ea830 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -110,7 +110,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = m_partsUpdateQueue.Dequeue(); - if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + if (part.ParentGroup.IsDeleted) continue; if (m_updateTimes.ContainsKey(part.UUID)) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a7f08d9..dff7269 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -234,35 +234,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (linkType) { case ScriptBaseClass.LINK_SET: - if (m_host.ParentGroup != null) - { - return new List(m_host.ParentGroup.Parts); - } - return ret; + return new List(m_host.ParentGroup.Parts); case ScriptBaseClass.LINK_ROOT: - if (m_host.ParentGroup != null) - { - ret = new List(); - ret.Add(m_host.ParentGroup.RootPart); - return ret; - } + ret = new List(); + ret.Add(m_host.ParentGroup.RootPart); return ret; case ScriptBaseClass.LINK_ALL_OTHERS: - if (m_host.ParentGroup == null) - return new List(); - ret = new List(m_host.ParentGroup.Parts); if (ret.Contains(m_host)) ret.Remove(m_host); + return ret; case ScriptBaseClass.LINK_ALL_CHILDREN: - if (m_host.ParentGroup == null) - return new List(); - ret = new List(m_host.ParentGroup.Parts); if (ret.Contains(m_host.ParentGroup.RootPart)) @@ -273,15 +260,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ret; default: - if (linkType < 0 || m_host.ParentGroup == null) + if (linkType < 0) return new List(); + SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); if (target == null) return new List(); ret = new List(); ret.Add(target); return ret; - } } @@ -1199,8 +1186,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (value != 0) { SceneObjectGroup group = m_host.ParentGroup; - if (group == null) - return; bool allow = true; foreach (SceneObjectPart part in group.Parts) @@ -1214,16 +1199,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!allow) return; + m_host.ScriptSetPhysicsStatus(true); } else + { m_host.ScriptSetPhysicsStatus(false); + } } if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM) { - if (m_host.ParentGroup != null) - m_host.ParentGroup.ScriptSetPhantomStatus(value != 0); + m_host.ParentGroup.ScriptSetPhantomStatus(value != 0); } if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS) @@ -1365,8 +1352,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void SetScale(SceneObjectPart part, LSL_Vector scale) { // TODO: this needs to trigger a persistance save as well - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + if (part == null || part.ParentGroup.IsDeleted) return; + if (scale.x < 0.01) scale.x = 0.01; if (scale.y < 0.01) @@ -1409,7 +1397,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); m_host.ClickAction = (byte)action; - if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; + m_host.ParentGroup.HasGroupChanged = true; m_host.ScheduleFullUpdate(); return; } @@ -2033,14 +2021,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else { // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. - SceneObjectGroup group = m_host.ParentGroup; - if (group != null) // a bit paranoid, maybe + SceneObjectPart rootPart = m_host.ParentGroup.RootPart; + if (rootPart != null) // better safe than sorry { - SceneObjectPart rootPart = group.RootPart; - if (rootPart != null) // again, better safe than sorry - { - SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); - } + SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); } } @@ -2128,15 +2112,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - if (local != 0) - force *= llGetRot(); + if (local != 0) + force *= llGetRot(); - m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); - } + m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); } } @@ -2146,15 +2127,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); - force.x = tmpForce.X; - force.y = tmpForce.Y; - force.z = tmpForce.Z; - } + Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); + force.x = tmpForce.X; + force.y = tmpForce.Y; + force.z = tmpForce.Z; } return force; @@ -3163,12 +3141,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetBuoyancy(double buoyancy) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); - } + m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); } } @@ -6238,12 +6214,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetVehicleType(int type) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetVehicleType(type); - } + m_host.ParentGroup.RootPart.SetVehicleType(type); } } @@ -6253,12 +6227,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); - } + m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); } } @@ -6267,13 +6238,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetVehicleVectorParam(int param, LSL_Vector vec) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, - new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); - } + m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, + new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); } } @@ -6282,37 +6251,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetVehicleRotationParam(int param, LSL_Rotation rot) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, - Rot2Quaternion(rot)); - } + m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); } } public void llSetVehicleFlags(int flags) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false); - } + m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false); } } public void llRemoveVehicleFlags(int flags) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) + + if (!m_host.ParentGroup.IsDeleted) { - if (!m_host.ParentGroup.IsDeleted) - { - m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true); - } + m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true); } } @@ -6467,11 +6429,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llVolumeDetect(int detect) { m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) - { - if (!m_host.ParentGroup.IsDeleted) - m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); - } + + if (!m_host.ParentGroup.IsDeleted) + m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); } /// @@ -7022,14 +6982,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else { // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. - SceneObjectGroup group = part.ParentGroup; - if (group != null) // a bit paranoid, maybe + SceneObjectPart rootPart = part.ParentGroup.RootPart; + if (rootPart != null) // better safe than sorry { - SceneObjectPart rootPart = group.RootPart; - if (rootPart != null) // again, better safe than sorry - { - SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); - } + SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); } } @@ -7278,13 +7234,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PRIM_PHANTOM: - if (remain < 1) + if (remain < 1) return; string ph = rules.Data[idx++].ToString(); - - if (m_host.ParentGroup != null) - m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); + m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); break; @@ -7307,8 +7261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; string temp = rules.Data[idx++].ToString(); - if (m_host.ParentGroup != null) - m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); + m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); break; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index d791885..7f3d84d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -672,13 +672,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater"); m_host.AddScriptLPS(1); - if (m_host.ParentGroup != null) - { - if (m_host.ParentGroup.RootPart != null) - { - m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); - } - } + + if (m_host.ParentGroup.RootPart != null) + m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); } // Teleport functions diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 3575889..8cebb4a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared return; } - part=part.ParentGroup.RootPart; // We detect objects only + part = part.ParentGroup.RootPart; // We detect objects only LinkNum = 0; // Not relevant diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index ef9b2ac..6e9f3ec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -766,13 +766,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; - if (part != null && part.ParentGroup != null) + if (part != null) m_Engine.World.DeleteSceneObject(part.ParentGroup, false); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; - if (part != null && part.ParentGroup != null) + if (part != null) part.Inventory.RemoveInventoryItem(m_ItemID); } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 0ac8b5c..08dc71e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -97,8 +97,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine return; m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); - if (part.ParentGroup != null) - part = part.ParentGroup.RootPart; + + part = part.ParentGroup.RootPart; if (part != null) { -- cgit v1.1 From 63bf71023772ea9c54687c5006fcf6649eb1139f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 01:37:35 +0100 Subject: Fix issue with llGetTorque() where it would only ever return a zero vector. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 --------- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4e7504a..982c492 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1536,15 +1536,6 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.setAngularImpulse(impulse); } - public Vector3 GetTorque() - { - if (m_parentGroup != null) - { - m_parentGroup.GetTorque(); - } - return Vector3.Zero; - } - /// /// Apply physics to this part. /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index dff7269..8d95546 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2202,7 +2202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetTorque() { m_host.AddScriptLPS(1); - Vector3 torque = m_host.GetTorque(); + Vector3 torque = m_host.ParentGroup.GetTorque(); return new LSL_Vector(torque.X,torque.Y,torque.Z); } -- cgit v1.1 From 10d883dc88d5d2170930ba9353eadbfa7f3e6bc7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 01:41:53 +0100 Subject: refactor: use ParentGroup.UUID directly instead of SOP.GetRootPartUUID() --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 23 ++++++---------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 982c492..68b24cd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2021,25 +2021,17 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 GetGeometricCenter() { if (PhysActor != null) - { return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); - } else - { return new Vector3(0, 0, 0); - } } public float GetMass() { if (PhysActor != null) - { return PhysActor.Mass; - } else - { return 0; - } } public Vector3 GetForce() @@ -2055,15 +2047,12 @@ namespace OpenSim.Region.Framework.Scenes client.SendObjectPropertiesReply(this); } - public UUID GetRootPartUUID() - { - return m_parentGroup.UUID; - } - /// /// Method for a prim to get it's world position from the group. - /// Remember, the Group Position simply gives the position of the group itself /// + /// + /// Remember, the Group Position simply gives the position of the group itself + /// /// A Linked Child Prim objects position in world public Vector3 GetWorldPosition() { @@ -3117,7 +3106,7 @@ namespace OpenSim.Region.Framework.Scenes UUID ownerID = _ownerID; UUID objectID = ParentGroup.RootPart.UUID; - UUID parentID = GetRootPartUUID(); + UUID parentID = ParentGroup.UUID; UUID soundID = UUID.Zero; Vector3 position = AbsolutePosition; // region local @@ -3156,7 +3145,7 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.PlaySoundMasterPrim = this; ownerID = _ownerID; objectID = ParentGroup.RootPart.UUID; - parentID = GetRootPartUUID(); + parentID = ParentGroup.UUID; position = AbsolutePosition; // region local regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; if (triggered) @@ -3167,7 +3156,7 @@ namespace OpenSim.Region.Framework.Scenes { ownerID = prim._ownerID; objectID = prim.ParentGroup.RootPart.UUID; - parentID = prim.GetRootPartUUID(); + parentID = prim.ParentGroup.UUID; position = prim.AbsolutePosition; // region local regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle; if (triggered) -- cgit v1.1 From 7eca929686bd2db1cb42f5c9740fd1d186cdc8b1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 02:09:41 +0100 Subject: Eliminate pointless checks of SOG.RootPart != null It's never possible for SOG to have no RootPart, except in the first few picosends of the big bang when it's pulled from region persistence or deserialized --- .../Linden/Caps/ObjectCaps/ObjectAdd.cs | 2 - .../Avatar/Attachments/AttachmentsModule.cs | 6 - .../EntityTransfer/EntityTransferModule.cs | 2 +- OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | 83 +++++---- .../Framework/Scenes/Scene.PacketHandlers.cs | 4 - OpenSim/Region/Framework/Scenes/Scene.cs | 14 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 194 ++++++++------------- .../World/TreePopulator/TreePopulatorModule.cs | 1 - .../Shared/Api/Implementation/LSL_Api.cs | 7 +- .../Shared/Api/Implementation/OSSL_Api.cs | 3 +- .../Region/ScriptEngine/XEngine/EventManager.cs | 6 +- 12 files changed, 119 insertions(+), 205 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index 15139a3..1c47f0e 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -322,8 +322,6 @@ namespace OpenSim.Region.ClientStack.Linden rootpart.NextOwnerMask = next_owner_mask; rootpart.Material = (byte)material; - - m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); responsedata["int_response_code"] = 200; //501; //410; //404; diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 587f35e..ffe76a8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -470,12 +470,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } - if (null == att.RootPart) - { - m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!"); - return; - } - InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); item = m_scene.InventoryService.GetItem(item); bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 82bdf20..766656c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1772,7 +1772,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer foreach (SceneObjectGroup gobj in m_attachments) { // If the prim group is null then something must have happened to it! - if (gobj != null && gobj.RootPart != null) + if (gobj != null) { // Set the parent localID to 0 so it transfers over properly. gobj.RootPart.SetParentLocalId(0); diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs index 5e75cae..0bb4044 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs @@ -118,59 +118,56 @@ namespace OpenSim.Region.DataSnapshot.Providers { SceneObjectPart m_rootPart = obj.RootPart; - if (m_rootPart != null) - { - ILandObject land = m_scene.LandChannel.GetLandObject(m_rootPart.AbsolutePosition.X, m_rootPart.AbsolutePosition.Y); + ILandObject land = m_scene.LandChannel.GetLandObject(m_rootPart.AbsolutePosition.X, m_rootPart.AbsolutePosition.Y); - XmlNode xmlobject = nodeFactory.CreateNode(XmlNodeType.Element, "object", ""); - node = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); - node.InnerText = obj.UUID.ToString(); - xmlobject.AppendChild(node); + XmlNode xmlobject = nodeFactory.CreateNode(XmlNodeType.Element, "object", ""); + node = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); + node.InnerText = obj.UUID.ToString(); + xmlobject.AppendChild(node); - node = nodeFactory.CreateNode(XmlNodeType.Element, "title", ""); - node.InnerText = m_rootPart.Name; - xmlobject.AppendChild(node); - - node = nodeFactory.CreateNode(XmlNodeType.Element, "description", ""); - node.InnerText = m_rootPart.Description; - xmlobject.AppendChild(node); + node = nodeFactory.CreateNode(XmlNodeType.Element, "title", ""); + node.InnerText = m_rootPart.Name; + xmlobject.AppendChild(node); - node = nodeFactory.CreateNode(XmlNodeType.Element, "flags", ""); - node.InnerText = String.Format("{0:x}", (uint)m_rootPart.Flags); - xmlobject.AppendChild(node); + node = nodeFactory.CreateNode(XmlNodeType.Element, "description", ""); + node.InnerText = m_rootPart.Description; + xmlobject.AppendChild(node); - node = nodeFactory.CreateNode(XmlNodeType.Element, "regionuuid", ""); - node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString(); - xmlobject.AppendChild(node); + node = nodeFactory.CreateNode(XmlNodeType.Element, "flags", ""); + node.InnerText = String.Format("{0:x}", (uint)m_rootPart.Flags); + xmlobject.AppendChild(node); - if (land != null && land.LandData != null) - { - node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", ""); - node.InnerText = land.LandData.GlobalID.ToString(); - xmlobject.AppendChild(node); - } - else - { - // Something is wrong with this object. Let's not list it. - m_log.WarnFormat("[DATASNAPSHOT]: Bad data for object {0} ({1}) in region {2}", obj.Name, obj.UUID, m_scene.RegionInfo.RegionName); - continue; - } + node = nodeFactory.CreateNode(XmlNodeType.Element, "regionuuid", ""); + node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString(); + xmlobject.AppendChild(node); - node = nodeFactory.CreateNode(XmlNodeType.Element, "location", ""); - Vector3 loc = obj.AbsolutePosition; - node.InnerText = loc.X.ToString() + "/" + loc.Y.ToString() + "/" + loc.Z.ToString(); + if (land != null && land.LandData != null) + { + node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", ""); + node.InnerText = land.LandData.GlobalID.ToString(); xmlobject.AppendChild(node); + } + else + { + // Something is wrong with this object. Let's not list it. + m_log.WarnFormat("[DATASNAPSHOT]: Bad data for object {0} ({1}) in region {2}", obj.Name, obj.UUID, m_scene.RegionInfo.RegionName); + continue; + } - string bestImage = GuessImage(obj); - if (bestImage != string.Empty) - { - node = nodeFactory.CreateNode(XmlNodeType.Element, "image", ""); - node.InnerText = bestImage; - xmlobject.AppendChild(node); - } + node = nodeFactory.CreateNode(XmlNodeType.Element, "location", ""); + Vector3 loc = obj.AbsolutePosition; + node.InnerText = loc.X.ToString() + "/" + loc.Y.ToString() + "/" + loc.Z.ToString(); + xmlobject.AppendChild(node); - parent.AppendChild(xmlobject); + string bestImage = GuessImage(obj); + if (bestImage != string.Empty) + { + node = nodeFactory.CreateNode(XmlNodeType.Element, "image", ""); + node.InnerText = bestImage; + xmlobject.AppendChild(node); } + + parent.AppendChild(xmlobject); } #pragma warning disable 0612 } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 44472b2..29d01d6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -191,10 +191,6 @@ namespace OpenSim.Region.Framework.Scenes if (part == null) return; - // The prim is in the process of being deleted. - if (null == part.ParentGroup.RootPart) - return; - // A deselect packet contains all the local prims being deselected. However, since selection is still // group based we only want the root prim to trigger a full update - otherwise on objects with many prims // we end up sending many duplicate ObjectUpdates diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7f5aea7..9794a34 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1743,14 +1743,6 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectGroup group in PrimsFromDB) { EventManager.TriggerOnSceneObjectLoaded(group); - - if (group.RootPart == null) - { - m_log.ErrorFormat( - "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", - group.Parts == null ? 0 : group.PrimCount); - } - AddRestoredSceneObject(group, true, true); SceneObjectPart rootPart = group.GetChildPart(group.UUID); rootPart.Flags &= ~PrimFlags.Scripted; @@ -4215,7 +4207,7 @@ namespace OpenSim.Region.Framework.Scenes // their scripts will actually run. // -- Leaf, Tue Aug 12 14:17:05 EDT 2008 SceneObjectPart parent = part.ParentGroup.RootPart; - if (parent != null && part.ParentGroup.IsAttachment) + if (part.ParentGroup.IsAttachment) return ScriptDanger(parent, parent.GetWorldPosition()); else return ScriptDanger(part, part.GetWorldPosition()); @@ -5015,7 +5007,9 @@ namespace OpenSim.Region.Framework.Scenes if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) { delete = true; - } else { + } + else + { ILandObject parcel = LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); if (parcel == null || parcel.LandData.Name == "NO LAND") diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 17a1bcc..6f963ac 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -362,7 +362,7 @@ namespace OpenSim.Region.Framework.Scenes /// protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { - if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) + if (sceneObject == null || sceneObject.RootPart.UUID == UUID.Zero) return false; if (Entities.ContainsKey(sceneObject.UUID)) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 74e8783..fca42c8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -254,14 +254,7 @@ namespace OpenSim.Region.Framework.Scenes /// public override string Name { - get - { - if (RootPart == null) - return String.Empty; - else - return RootPart.Name; - } - + get { return RootPart.Name; } set { RootPart.Name = value; } } @@ -1054,7 +1047,7 @@ namespace OpenSim.Region.Framework.Scenes { part.SetParent(this); part.LinkNum = m_parts.Add(part.UUID, part); - if (part.LinkNum == 2 && RootPart != null) + if (part.LinkNum == 2) RootPart.LinkNum = 1; } @@ -1537,137 +1530,93 @@ namespace OpenSim.Region.Framework.Scenes public void applyImpulse(Vector3 impulse) { - // We check if rootpart is null here because scripts don't delete if you delete the host. - // This means that unfortunately, we can pass a null physics actor to Simulate! - // Make sure we don't do that! - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) + if (IsAttachment) { - if (IsAttachment) + ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); + if (avatar != null) { - ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); - if (avatar != null) - { - avatar.PushForce(impulse); - } + avatar.PushForce(impulse); } - else + } + else + { + if (RootPart.PhysActor != null) { - if (rootpart.PhysActor != null) - { - rootpart.PhysActor.AddForce(impulse, true); - m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); - } + RootPart.PhysActor.AddForce(impulse, true); + m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); } } } public void applyAngularImpulse(Vector3 impulse) { - // We check if rootpart is null here because scripts don't delete if you delete the host. - // This means that unfortunately, we can pass a null physics actor to Simulate! - // Make sure we don't do that! - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) + if (RootPart.PhysActor != null) { - if (rootpart.PhysActor != null) + if (!IsAttachment) { - if (!IsAttachment) - { - rootpart.PhysActor.AddAngularForce(impulse, true); - m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); - } + RootPart.PhysActor.AddAngularForce(impulse, true); + m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); } } } public void setAngularImpulse(Vector3 impulse) { - // We check if rootpart is null here because scripts don't delete if you delete the host. - // This means that unfortunately, we can pass a null physics actor to Simulate! - // Make sure we don't do that! - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) + if (RootPart.PhysActor != null) { - if (rootpart.PhysActor != null) + if (!IsAttachment) { - if (!IsAttachment) - { - rootpart.PhysActor.Torque = impulse; - m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); - } + RootPart.PhysActor.Torque = impulse; + m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); } } } public Vector3 GetTorque() { - // We check if rootpart is null here because scripts don't delete if you delete the host. - // This means that unfortunately, we can pass a null physics actor to Simulate! - // Make sure we don't do that! - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) + if (RootPart.PhysActor != null) { - if (rootpart.PhysActor != null) + if (!IsAttachment) { - if (!IsAttachment) - { - Vector3 torque = rootpart.PhysActor.Torque; - return torque; - } + Vector3 torque = RootPart.PhysActor.Torque; + return torque; } } + return Vector3.Zero; } public void moveToTarget(Vector3 target, float tau) { - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) + if (IsAttachment) { - if (IsAttachment) + ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); + if (avatar != null) { - ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); - if (avatar != null) - { - avatar.MoveToTarget(target, false); - } + avatar.MoveToTarget(target, false); } - else + } + else + { + if (RootPart.PhysActor != null) { - if (rootpart.PhysActor != null) - { - rootpart.PhysActor.PIDTarget = target; - rootpart.PhysActor.PIDTau = tau; - rootpart.PhysActor.PIDActive = true; - } + RootPart.PhysActor.PIDTarget = target; + RootPart.PhysActor.PIDTau = tau; + RootPart.PhysActor.PIDActive = true; } } } public void stopMoveToTarget() { - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) - { - if (rootpart.PhysActor != null) - { - rootpart.PhysActor.PIDActive = false; - } - } + if (RootPart.PhysActor != null) + RootPart.PhysActor.PIDActive = false; } public void stopLookAt() { - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) - { - if (rootpart.PhysActor != null) - { - rootpart.PhysActor.APIDActive = false; - } - } - + if (RootPart.PhysActor != null) + RootPart.PhysActor.APIDActive = false; } /// @@ -1678,22 +1627,18 @@ namespace OpenSim.Region.Framework.Scenes /// Number of seconds over which to reach target public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) { - SceneObjectPart rootpart = m_rootPart; - if (rootpart != null) + if (RootPart.PhysActor != null) { - if (rootpart.PhysActor != null) + if (height != 0f) { - if (height != 0f) - { - rootpart.PhysActor.PIDHoverHeight = height; - rootpart.PhysActor.PIDHoverType = hoverType; - rootpart.PhysActor.PIDTau = tau; - rootpart.PhysActor.PIDHoverActive = true; - } - else - { - rootpart.PhysActor.PIDHoverActive = false; - } + RootPart.PhysActor.PIDHoverHeight = height; + RootPart.PhysActor.PIDHoverType = hoverType; + RootPart.PhysActor.PIDTau = tau; + RootPart.PhysActor.PIDHoverActive = true; + } + else + { + RootPart.PhysActor.PIDHoverActive = false; } } } @@ -3056,28 +3001,23 @@ namespace OpenSim.Region.Framework.Scenes int yaxis = 4; int zaxis = 8; - if (m_rootPart != null) - { - setX = ((axis & xaxis) != 0) ? true : false; - setY = ((axis & yaxis) != 0) ? true : false; - setZ = ((axis & zaxis) != 0) ? true : false; - - float setval = (rotate10 > 0) ? 1f : 0f; + setX = ((axis & xaxis) != 0) ? true : false; + setY = ((axis & yaxis) != 0) ? true : false; + setZ = ((axis & zaxis) != 0) ? true : false; - if (setX) - m_rootPart.RotationAxis.X = setval; - if (setY) - m_rootPart.RotationAxis.Y = setval; - if (setZ) - m_rootPart.RotationAxis.Z = setval; + float setval = (rotate10 > 0) ? 1f : 0f; - if (setX || setY || setZ) - { - m_rootPart.SetPhysicsAxisRotation(); - } + if (setX) + RootPart.RotationAxis.X = setval; + if (setY) + RootPart.RotationAxis.Y = setval; + if (setZ) + RootPart.RotationAxis.Z = setval; - } + if (setX || setY || setZ) + RootPart.SetPhysicsAxisRotation(); } + public int registerRotTargetWaypoint(Quaternion target, float tolerance) { scriptRotTarget waypoint = new scriptRotTarget(); @@ -3205,7 +3145,13 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint idx in m_rotTargets.Keys) { scriptRotTarget target = m_rotTargets[idx]; - double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2; + double angle + = Math.Acos( + target.targetRot.X * m_rootPart.RotationOffset.X + + target.targetRot.Y * m_rootPart.RotationOffset.Y + + target.targetRot.Z * m_rootPart.RotationOffset.Z + + target.targetRot.W * m_rootPart.RotationOffset.W) + * 2; if (angle < 0) angle = -angle; if (angle > Math.PI) angle = (Math.PI * 2 - angle); if (angle <= target.tolerance) diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index 421da36..feca7d3 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -381,7 +381,6 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator { SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; - m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); m_scene.ForEachClient(delegate(IClientAPI controller) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8d95546..2fd98f6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2767,8 +2767,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // If either of these are null, then there was an unknown error. if (new_group == null) continue; - if (new_group.RootPart == null) - continue; // objects rezzed with this method are die_at_edge by default. new_group.RootPart.SetDieAtEdge(true); @@ -6983,10 +6981,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. SceneObjectPart rootPart = part.ParentGroup.RootPart; - if (rootPart != null) // better safe than sorry - { - SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); - } + SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); } break; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7f3d84d..3ddd79b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -673,8 +673,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - if (m_host.ParentGroup.RootPart != null) - m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); + m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); } // Teleport functions diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 08dc71e..5c4174e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -99,11 +99,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); part = part.ParentGroup.RootPart; - - if (part != null) - { - money(part.LocalId, agentID, amount); - } + money(part.LocalId, agentID, amount); } /// -- cgit v1.1 From c491cdcb952ba50b84a2ba710bb3771421cc61f2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 02:18:31 +0100 Subject: refactor: use SOG register target waypoints and rots directly instead of calling through the SOP, which doesn't make conceptual sense anyway. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 20 -------------------- .../Shared/Api/Implementation/LSL_Api.cs | 10 ++++++---- 2 files changed, 6 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 68b24cd..a8f2ebd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4766,26 +4766,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public int registerTargetWaypoint(Vector3 target, float tolerance) - { - return m_parentGroup.registerTargetWaypoint(target, tolerance); - } - - public void unregisterTargetWaypoint(int handle) - { - m_parentGroup.unregisterTargetWaypoint(handle); - } - - public int registerRotTargetWaypoint(Quaternion target, float tolerance) - { - return m_parentGroup.registerRotTargetWaypoint(target, tolerance); - } - - public void unregisterRotTargetWaypoint(int handle) - { - m_parentGroup.unregisterRotTargetWaypoint(handle); - } - public void SetCameraAtOffset(Vector3 v) { m_cameraAtOffset = v; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2fd98f6..88e884d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2141,25 +2141,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llTarget(LSL_Vector position, double range) { m_host.AddScriptLPS(1); - return m_host.registerTargetWaypoint(new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); + return m_host.ParentGroup.registerTargetWaypoint( + new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); } public void llTargetRemove(int number) { m_host.AddScriptLPS(1); - m_host.unregisterTargetWaypoint(number); + m_host.ParentGroup.unregisterTargetWaypoint(number); } public LSL_Integer llRotTarget(LSL_Rotation rot, double error) { m_host.AddScriptLPS(1); - return m_host.registerRotTargetWaypoint(new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); + return m_host.ParentGroup.registerRotTargetWaypoint( + new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); } public void llRotTargetRemove(int number) { m_host.AddScriptLPS(1); - m_host.unregisterRotTargetWaypoint(number); + m_host.ParentGroup.unregisterRotTargetWaypoint(number); } public void llMoveToTarget(LSL_Vector target, double tau) -- cgit v1.1 From 616e672fce793350071bff538db4a8dc033f6259 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 02:43:17 +0100 Subject: If the user receiving an inventory folder has left the scene by the time the acceptence message arrives, then don't send them an inventory update. Doing so causes a NullReferenceException --- .../Avatar/Inventory/Transfer/InventoryTransferModule.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index b4f69e6..f46d9f7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -208,9 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); if (user != null) - { user.ControllingClient.SendBulkUpdateInventory(folderCopy); - } // HACK!! im.imSessionID = folderID.Guid; @@ -240,9 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); if (user != null) - { user.ControllingClient.SendBulkUpdateInventory(itemCopy); - } // HACK!! im.imSessionID = itemID.Guid; @@ -288,7 +284,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID)); - fromUser.ControllingClient.SendBulkUpdateInventory(folder); + // If the user has left the scene by the time the message comes back then we can't send + // them the update. + if (fromUser != null) + fromUser.ControllingClient.SendBulkUpdateInventory(folder); }); } } -- cgit v1.1 From 1bf29d60e1a6839a1b81e0afc656a97f252e13cc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 22:05:05 +0100 Subject: Remove code which was automatically deleting non-root prims from scene objects that had previous been attachments. Looks like this code was accidentally uncommented in e1b5c612 from feb 2010. Appears to resolve the rest of http://opensimulator.org/mantis/view.php?id=5664 --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index fcb7eea..1a591ee 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -946,6 +946,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess rootPart.ScheduleFullUpdate(); } + +// m_log.DebugFormat( +// "[InventoryAccessModule]: Rezzed {0} {1} {2} for {3}", +// group.Name, group.LocalId, group.UUID, remoteClient.Name); } if (!m_Scene.Permissions.BypassPermissions()) -- cgit v1.1 From 8b83c4a4331e759b83112a4e04558ed961ff891a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 23:06:57 +0100 Subject: Remove pointless NRE check in IAM.RezObject() since this can never occur --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 1a591ee..76a1cd0 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -865,21 +865,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.SetFromItemID(itemID); } - SceneObjectPart rootPart = null; - - try - { - rootPart = group.GetChildPart(group.UUID); - } - catch (NullReferenceException) - { - string isAttachment = ""; - - if (attachment) - isAttachment = " Object was an attachment"; - - m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); - } + SceneObjectPart rootPart = group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not // affect the name stored in the serialization, transfer -- cgit v1.1 From e30651b9315c121d57d8c4077cf6bdfccb83aa68 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 23:09:14 +0100 Subject: use group.RootPart in IAM.RezObject() rather than group.GetChildPart(group.UUID); --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 76a1cd0..e0ff5a8 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -865,7 +865,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.SetFromItemID(itemID); } - SceneObjectPart rootPart = group.GetChildPart(group.UUID); + SceneObjectPart rootPart = group.RootPart; // Since renaming the item in the inventory does not // affect the name stored in the serialization, transfer -- cgit v1.1 From 712d44635a0f4552fbac4c6423ab88e027cef8a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 23:14:50 +0100 Subject: refactor: Move sanity checks to the top of IAM.RezObject() to make the code more readable --- .../InventoryAccess/InventoryAccessModule.cs | 434 ++++++++++----------- 1 file changed, 215 insertions(+), 219 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e0ff5a8..5778dff 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -700,276 +700,272 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, scale, false); - // Rez object InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_Scene.InventoryService.GetItem(item); - if (item != null) + if (item == null) { - item.Owner = remoteClient.AgentId; + m_log.WarnFormat( + "[InventoryAccessModule]: Could not find item {0} for {1} in RezObject()", + itemID, remoteClient.Name); - AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); + return null; + } - SceneObjectGroup group = null; + item.Owner = remoteClient.AgentId; + AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); - if (rezAsset != null) - { - UUID itemId = UUID.Zero; + if (rezAsset == null) + { + m_log.WarnFormat( + "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", + item.AssetID, item.Name, item.ID, remoteClient.Name); - // If we have permission to copy then link the rezzed object back to the user inventory - // item that it came from. This allows us to enable 'save object to inventory' - if (!m_Scene.Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - itemId = item.ID; - } - } - else - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - // Brave new fullperm world - itemId = item.ID; - } - } + return null; + } - string xmlData = Utils.BytesToString(rezAsset.Data); - List objlist = - new List(); - List veclist = new List(); + SceneObjectGroup group = null; + UUID itemId = UUID.Zero; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xmlData); - XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); - if (e == null || attachment) // Single - { - SceneObjectGroup g = - SceneObjectSerializer.FromOriginalXmlFormat( - itemId, xmlData); - objlist.Add(g); - veclist.Add(new Vector3(0, 0, 0)); - - float offsetHeight = 0; - pos = m_Scene.GetNewRezLocation( - RayStart, RayEnd, RayTargetID, Quaternion.Identity, - BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); - pos.Z += offsetHeight; - } - else - { - XmlElement coll = (XmlElement)e; - float bx = Convert.ToSingle(coll.GetAttribute("x")); - float by = Convert.ToSingle(coll.GetAttribute("y")); - float bz = Convert.ToSingle(coll.GetAttribute("z")); - Vector3 bbox = new Vector3(bx, by, bz); + // If we have permission to copy then link the rezzed object back to the user inventory + // item that it came from. This allows us to enable 'save object to inventory' + if (!m_Scene.Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + itemId = item.ID; + } + } + else + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + // Brave new fullperm world + itemId = item.ID; + } + } + + string xmlData = Utils.BytesToString(rezAsset.Data); + List objlist = + new List(); + List veclist = new List(); - pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, - RayTargetID, Quaternion.Identity, - BypassRayCast, bRayEndIsIntersection, true, - bbox, false); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xmlData); + XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); + if (e == null || attachment) // Single + { + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, xmlData); + objlist.Add(g); + veclist.Add(new Vector3(0, 0, 0)); + + float offsetHeight = 0; + pos = m_Scene.GetNewRezLocation( + RayStart, RayEnd, RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); + pos.Z += offsetHeight; + } + else + { + XmlElement coll = (XmlElement)e; + float bx = Convert.ToSingle(coll.GetAttribute("x")); + float by = Convert.ToSingle(coll.GetAttribute("y")); + float bz = Convert.ToSingle(coll.GetAttribute("z")); + Vector3 bbox = new Vector3(bx, by, bz); - pos -= bbox / 2; + pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, + RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, + bbox, false); - XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); - foreach (XmlNode n in groups) - { - SceneObjectGroup g = - SceneObjectSerializer.FromOriginalXmlFormat( - itemId, n.OuterXml); - objlist.Add(g); - XmlElement el = (XmlElement)n; - - string rawX = el.GetAttribute("offsetx"); - string rawY = el.GetAttribute("offsety"); - string rawZ = el.GetAttribute("offsetz"); + pos -= bbox / 2; + + XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); + foreach (XmlNode n in groups) + { + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, n.OuterXml); + objlist.Add(g); + XmlElement el = (XmlElement)n; + + string rawX = el.GetAttribute("offsetx"); + string rawY = el.GetAttribute("offsety"); + string rawZ = el.GetAttribute("offsetz"); // // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", // g.Name, rawX, rawY, rawZ); - - float x = Convert.ToSingle(rawX); - float y = Convert.ToSingle(rawY); - float z = Convert.ToSingle(rawZ); - veclist.Add(new Vector3(x, y, z)); - } - } - int primcount = 0; - foreach (SceneObjectGroup g in objlist) - primcount += g.PrimCount; + float x = Convert.ToSingle(rawX); + float y = Convert.ToSingle(rawY); + float z = Convert.ToSingle(rawZ); + veclist.Add(new Vector3(x, y, z)); + } + } - if (!m_Scene.Permissions.CanRezObject( - primcount, remoteClient.AgentId, pos) - && !attachment) - { - // The client operates in no fail mode. It will - // have already removed the item from the folder - // if it's no copy. - // Put it back if it's not an attachment - // - if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) - remoteClient.SendBulkUpdateInventory(item); + int primcount = 0; + foreach (SceneObjectGroup g in objlist) + primcount += g.PrimCount; - return null; - } + if (!m_Scene.Permissions.CanRezObject( + primcount, remoteClient.AgentId, pos) + && !attachment) + { + // The client operates in no fail mode. It will + // have already removed the item from the folder + // if it's no copy. + // Put it back if it's not an attachment + // + if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) + remoteClient.SendBulkUpdateInventory(item); - for (int i = 0 ; i < objlist.Count; i++) - { - group = objlist[i]; + return null; + } + + for (int i = 0 ; i < objlist.Count; i++) + { + group = objlist[i]; // Vector3 storedPosition = group.AbsolutePosition; - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); - } + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); + } - group.RootPart.FromFolderID = item.Folder; + group.RootPart.FromFolderID = item.Folder; - // If it's rezzed in world, select it. Much easier to - // find small items. - // - if (!attachment) - { - group.RootPart.CreateSelected = true; - foreach (SceneObjectPart child in group.Parts) - child.CreateSelected = true; - } + // If it's rezzed in world, select it. Much easier to + // find small items. + // + if (!attachment) + { + group.RootPart.CreateSelected = true; + foreach (SceneObjectPart child in group.Parts) + child.CreateSelected = true; + } - group.ResetIDs(); + group.ResetIDs(); - if (attachment) - { - group.RootPart.Flags |= PrimFlags.Phantom; - group.IsAttachment = true; - } + if (attachment) + { + group.RootPart.Flags |= PrimFlags.Phantom; + group.IsAttachment = true; + } - // If we're rezzing an attachment then don't ask - // AddNewSceneObject() to update the client since - // we'll be doing that later on. Scheduling more than - // one full update during the attachment - // process causes some clients to fail to display the - // attachment properly. - m_Scene.AddNewSceneObject(group, true, false); - - // if attachment we set it's asset id so object updates - // can reflect that, if not, we set it's position in world. - if (!attachment) - { - group.ScheduleGroupForFullUpdate(); - - group.AbsolutePosition = pos + veclist[i]; - } - else - { - group.SetFromItemID(itemID); - } + // If we're rezzing an attachment then don't ask + // AddNewSceneObject() to update the client since + // we'll be doing that later on. Scheduling more than + // one full update during the attachment + // process causes some clients to fail to display the + // attachment properly. + m_Scene.AddNewSceneObject(group, true, false); + + // if attachment we set it's asset id so object updates + // can reflect that, if not, we set it's position in world. + if (!attachment) + { + group.ScheduleGroupForFullUpdate(); - SceneObjectPart rootPart = group.RootPart; + group.AbsolutePosition = pos + veclist[i]; + } + else + { + group.SetFromItemID(itemID); + } - // Since renaming the item in the inventory does not - // affect the name stored in the serialization, transfer - // the correct name from the inventory to the - // object itself before we rez. - // - // Only do these for the first object if we are rezzing a coalescence. - if (i == 0) - { - rootPart.Name = item.Name; - rootPart.Description = item.Description; - rootPart.ObjectSaleType = item.SaleType; - rootPart.SalePrice = item.SalePrice; - } + SceneObjectPart rootPart = group.RootPart; - group.SetGroup(remoteClient.ActiveGroupId, remoteClient); - if ((rootPart.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0) - { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; + // Since renaming the item in the inventory does not + // affect the name stored in the serialization, transfer + // the correct name from the inventory to the + // object itself before we rez. + // + // Only do these for the first object if we are rezzing a coalescence. + if (i == 0) + { + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; + } - if (m_Scene.Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart part in group.Parts) - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - } - part.GroupMask = 0; // DO NOT propagate here - } - - group.ApplyNextOwnerPermissions(); - } - } + group.SetGroup(remoteClient.ActiveGroupId, remoteClient); + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + if (m_Scene.Permissions.PropagatePermissions()) + { foreach (SceneObjectPart part in group.Parts) { - if ((part.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0) + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.Owner; - part.Inventory.ChangeInventoryOwner(item.Owner); - part.GroupMask = 0; // DO NOT propagate here + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; } - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; + part.GroupMask = 0; // DO NOT propagate here } - rootPart.TrimPermissions(); - - if (!attachment) - { - if (group.RootPart.Shape.PCode == (byte)PCode.Prim) - group.ClearPartAttachmentData(); - - // Fire on_rez - group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); - rootPart.ParentGroup.ResumeScripts(); - - rootPart.ScheduleFullUpdate(); - } - -// m_log.DebugFormat( -// "[InventoryAccessModule]: Rezzed {0} {1} {2} for {3}", -// group.Name, group.LocalId, group.UUID, remoteClient.Name); + group.ApplyNextOwnerPermissions(); } + } - if (!m_Scene.Permissions.BypassPermissions()) + foreach (SceneObjectPart part in group.Parts) + { + if ((part.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) - { - // If this is done on attachments, no - // copy ones will be lost, so avoid it - // - if (!attachment) - { - List uuids = new List(); - uuids.Add(item.ID); - m_Scene.InventoryService.DeleteItems(item.Owner, uuids); - } - } + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); + part.GroupMask = 0; // DO NOT propagate here } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; } - else + + rootPart.TrimPermissions(); + + if (!attachment) { - m_log.WarnFormat( - "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", item.AssetID, item.Name, item.ID, remoteClient.Name); + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + group.ClearPartAttachmentData(); + + // Fire on_rez + group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); + rootPart.ParentGroup.ResumeScripts(); + + rootPart.ScheduleFullUpdate(); } - return group; +// m_log.DebugFormat( +// "[InventoryAccessModule]: Rezzed {0} {1} {2} for {3}", +// group.Name, group.LocalId, group.UUID, remoteClient.Name); } - else + + if (!m_Scene.Permissions.BypassPermissions()) { - m_log.WarnFormat( - "[InventoryAccessModule]: Could not find item {0} for {1} in RezObject()", - itemID, remoteClient.Name); + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + { + // If this is done on attachments, no + // copy ones will be lost, so avoid it + // + if (!attachment) + { + List uuids = new List(); + uuids.Add(item.ID); + m_Scene.InventoryService.DeleteItems(item.Owner, uuids); + } + } } - return null; + return group; } protected void AddUserData(SceneObjectGroup sog) -- cgit v1.1 From cc8897127b30b90bae1adfe7d6968974540cc669 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 23:37:03 +0100 Subject: remove the pointless m_Scene.GetNewRezLocation() call at the top of IAM.RezObject() since its always recalculated later on anyway --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 5778dff..9cad003 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -693,12 +693,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); - - byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); - Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); - Vector3 pos = m_Scene.GetNewRezLocation( - RayStart, RayEnd, RayTargetID, Quaternion.Identity, - BypassRayCast, bRayEndIsIntersection, true, scale, false); InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_Scene.InventoryService.GetItem(item); @@ -731,7 +725,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) + == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { itemId = item.ID; } @@ -749,6 +744,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess List objlist = new List(); List veclist = new List(); + byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); + Vector3 pos; XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlData); -- cgit v1.1 From 3e86064d6bdf46eb3dcbb9e9058cd7226f9e5367 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Sep 2011 23:49:38 +0100 Subject: refactor: factor out DoPostRezWhenFromItem() from IAM.RezObject() --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 9cad003..41f0e8c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -946,6 +946,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // group.Name, group.LocalId, group.UUID, remoteClient.Name); } + DoPostRezWhenFromItem(item, attachment); + + return group; + } + + private void DoPostRezWhenFromItem(InventoryItemBase item, bool isAttachment) + { if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) @@ -953,7 +960,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // If this is done on attachments, no // copy ones will be lost, so avoid it // - if (!attachment) + if (!isAttachment) { List uuids = new List(); uuids.Add(item.ID); @@ -961,8 +968,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } - - return group; } protected void AddUserData(SceneObjectGroup sog) -- cgit v1.1 From 01146bb3e3b60fd3ab54a1321fb58fe2e8cfbf1e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 00:04:22 +0100 Subject: factor out a section of IAM.RezObject() into DoPreRezWhenFromItem() --- .../InventoryAccess/InventoryAccessModule.cs | 88 ++++++++++++---------- 1 file changed, 48 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 41f0e8c..9bc7a09 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -822,7 +822,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return null; } - for (int i = 0 ; i < objlist.Count; i++) + for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; @@ -832,8 +832,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); } - group.RootPart.FromFolderID = item.Folder; - // If it's rezzed in world, select it. Much easier to // find small items. // @@ -890,44 +888,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); - if ((rootPart.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0) - { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; - - if (m_Scene.Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart part in group.Parts) - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - } - part.GroupMask = 0; // DO NOT propagate here - } - - group.ApplyNextOwnerPermissions(); - } - } - foreach (SceneObjectPart part in group.Parts) - { - if ((part.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0) - { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.Owner; - part.Inventory.ChangeInventoryOwner(item.Owner); - part.GroupMask = 0; // DO NOT propagate here - } - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - } - - rootPart.TrimPermissions(); + DoPreRezWhenFromItem(item, group); if (!attachment) { @@ -951,6 +913,52 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return group; } + private void DoPreRezWhenFromItem(InventoryItemBase item, SceneObjectGroup so) + { + so.RootPart.FromFolderID = item.Folder; + + SceneObjectPart rootPart = so.RootPart; + + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + + if (m_Scene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart part in so.Parts) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + } + part.GroupMask = 0; // DO NOT propagate here + } + + so.ApplyNextOwnerPermissions(); + } + } + + foreach (SceneObjectPart part in so.Parts) + { + if ((part.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); + part.GroupMask = 0; // DO NOT propagate here + } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + rootPart.TrimPermissions(); + } + private void DoPostRezWhenFromItem(InventoryItemBase item, bool isAttachment) { if (!m_Scene.Permissions.BypassPermissions()) -- cgit v1.1 From 15ea82e925af419f811a3c8c603bdc1e9103d22c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 00:25:05 +0100 Subject: move more of IAM.RezObject() into DoPreRezWhenFromItem() --- .../InventoryAccess/InventoryAccessModule.cs | 148 ++++++++++++--------- 1 file changed, 85 insertions(+), 63 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 9bc7a09..e94d059 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -803,24 +803,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - int primcount = 0; - foreach (SceneObjectGroup g in objlist) - primcount += g.PrimCount; - - if (!m_Scene.Permissions.CanRezObject( - primcount, remoteClient.AgentId, pos) - && !attachment) - { - // The client operates in no fail mode. It will - // have already removed the item from the folder - // if it's no copy. - // Put it back if it's not an attachment - // - if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) - remoteClient.SendBulkUpdateInventory(item); - + if (!DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) return null; - } for (int i = 0; i < objlist.Count; i++) { @@ -829,7 +813,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); + m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); } // If it's rezzed in world, select it. Much easier to @@ -873,24 +857,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess SceneObjectPart rootPart = group.RootPart; - // Since renaming the item in the inventory does not - // affect the name stored in the serialization, transfer - // the correct name from the inventory to the - // object itself before we rez. - // - // Only do these for the first object if we are rezzing a coalescence. - if (i == 0) - { - rootPart.Name = item.Name; - rootPart.Description = item.Description; - rootPart.ObjectSaleType = item.SaleType; - rootPart.SalePrice = item.SalePrice; - } - group.SetGroup(remoteClient.ActiveGroupId, remoteClient); - DoPreRezWhenFromItem(item, group); - if (!attachment) { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) @@ -913,52 +881,106 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return group; } - private void DoPreRezWhenFromItem(InventoryItemBase item, SceneObjectGroup so) + /// + /// Do pre-rez processing when the object comes from an item. + /// + /// + /// + /// + /// + /// + /// true if we can processed with rezzing, false if we need to abort + private bool DoPreRezWhenFromItem( + IClientAPI remoteClient, InventoryItemBase item, List objlist, Vector3 pos, bool isAttachment) { - so.RootPart.FromFolderID = item.Folder; + int primcount = 0; + foreach (SceneObjectGroup g in objlist) + primcount += g.PrimCount; + + if (!m_Scene.Permissions.CanRezObject( + primcount, remoteClient.AgentId, pos) + && !isAttachment) + { + // The client operates in no fail mode. It will + // have already removed the item from the folder + // if it's no copy. + // Put it back if it's not an attachment + // + if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) + remoteClient.SendBulkUpdateInventory(item); - SceneObjectPart rootPart = so.RootPart; + return false; + } - if ((rootPart.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0) + for (int i = 0; i < objlist.Count; i++) { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; + SceneObjectGroup so = objlist[i]; + SceneObjectPart rootPart = so.RootPart; + + // Since renaming the item in the inventory does not + // affect the name stored in the serialization, transfer + // the correct name from the inventory to the + // object itself before we rez. + // + // Only do these for the first object if we are rezzing a coalescence. + if (i == 0) + { + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; + } - if (m_Scene.Permissions.PropagatePermissions()) + rootPart.FromFolderID = item.Folder; + + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) { - foreach (SceneObjectPart part in so.Parts) + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + + if (m_Scene.Permissions.PropagatePermissions()) { - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + foreach (SceneObjectPart part in so.Parts) { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + } + part.GroupMask = 0; // DO NOT propagate here } - part.GroupMask = 0; // DO NOT propagate here + + so.ApplyNextOwnerPermissions(); } - - so.ApplyNextOwnerPermissions(); } - } - - foreach (SceneObjectPart part in so.Parts) - { - if ((part.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0) + + foreach (SceneObjectPart part in so.Parts) { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.Owner; - part.Inventory.ChangeInventoryOwner(item.Owner); - part.GroupMask = 0; // DO NOT propagate here + if ((part.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); + part.GroupMask = 0; // DO NOT propagate here + } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; } - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; + + rootPart.TrimPermissions(); } - rootPart.TrimPermissions(); + return true; } + /// + /// Do post-rez processing when the object comes from an item. + /// + /// + /// private void DoPostRezWhenFromItem(InventoryItemBase item, bool isAttachment) { if (!m_Scene.Permissions.BypassPermissions()) -- cgit v1.1 From 9c0a03731d531430d5c2b8b43d2384c0dd086f88 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 00:41:21 +0100 Subject: Move more of IAM.RezObject() into DoPreRezWhenFromItem() --- .../InventoryAccess/InventoryAccessModule.cs | 51 ++++++++++++---------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 +-- 2 files changed, 29 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e94d059..f8515b4 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -719,26 +719,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } SceneObjectGroup group = null; - UUID itemId = UUID.Zero; - - // If we have permission to copy then link the rezzed object back to the user inventory - // item that it came from. This allows us to enable 'save object to inventory' - if (!m_Scene.Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) - == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - itemId = item.ID; - } - } - else - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - // Brave new fullperm world - itemId = item.ID; - } - } string xmlData = Utils.BytesToString(rezAsset.Data); List objlist = @@ -753,8 +733,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (e == null || attachment) // Single { SceneObjectGroup g = - SceneObjectSerializer.FromOriginalXmlFormat( - itemId, xmlData); + SceneObjectSerializer.FromOriginalXmlFormat(UUID.Zero, xmlData); + objlist.Add(g); veclist.Add(new Vector3(0, 0, 0)); @@ -783,8 +763,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (XmlNode n in groups) { SceneObjectGroup g = - SceneObjectSerializer.FromOriginalXmlFormat( - itemId, n.OuterXml); + SceneObjectSerializer.FromOriginalXmlFormat(UUID.Zero, n.OuterXml); + objlist.Add(g); XmlElement el = (XmlElement)n; @@ -893,6 +873,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess private bool DoPreRezWhenFromItem( IClientAPI remoteClient, InventoryItemBase item, List objlist, Vector3 pos, bool isAttachment) { + UUID fromUserInventoryItemId = UUID.Zero; + + // If we have permission to copy then link the rezzed object back to the user inventory + // item that it came from. This allows us to enable 'save object to inventory' + if (!m_Scene.Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) + == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + fromUserInventoryItemId = item.ID; + } + } + else + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + // Brave new fullperm world + fromUserInventoryItemId = item.ID; + } + } + int primcount = 0; foreach (SceneObjectGroup g in objlist) primcount += g.PrimCount; @@ -958,6 +959,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (SceneObjectPart part in so.Parts) { + part.FromUserInventoryItemID = fromUserInventoryItemId; + if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a8f2ebd..9d573db 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -208,13 +208,12 @@ namespace OpenSim.Region.Framework.Scenes /// private UUID m_fromUserInventoryItemID; - public UUID FromUserInventoryItemID { get { return m_fromUserInventoryItemID; } + set { m_fromUserInventoryItemID = value; } } - - + public scriptEvents AggregateScriptEvents; -- cgit v1.1 From af7c6c5f39dc05dccb891e7bc19ec158de7718a9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 00:50:16 +0100 Subject: stop passing FromUserInventoryItemID right down into the deserializer. the code becomes simpler if this is set from the outside - only one place needs to do this. --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 6 ++---- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 15 ++------------- .../Scenes/Serialization/SceneObjectSerializer.cs | 16 +++------------- 3 files changed, 7 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index f8515b4..e6b58b3 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -732,8 +732,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); if (e == null || attachment) // Single { - SceneObjectGroup g = - SceneObjectSerializer.FromOriginalXmlFormat(UUID.Zero, xmlData); + SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); objlist.Add(g); veclist.Add(new Vector3(0, 0, 0)); @@ -762,8 +761,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); foreach (XmlNode n in groups) { - SceneObjectGroup g = - SceneObjectSerializer.FromOriginalXmlFormat(UUID.Zero, n.OuterXml); + SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); objlist.Add(g); XmlElement el = (XmlElement)n; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9d573db..04fef83 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1904,22 +1904,11 @@ namespace OpenSim.Region.Framework.Scenes /// public static SceneObjectPart FromXml(XmlTextReader xmlReader) { - return FromXml(UUID.Zero, xmlReader); - } - - /// - /// Restore this part from the serialized xml representation. - /// - /// The inventory id from which this part came, if applicable - /// - /// - public static SceneObjectPart FromXml(UUID fromUserInventoryItemId, XmlTextReader xmlReader) - { SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); - part.m_fromUserInventoryItemID = fromUserInventoryItemId; // for tempOnRez objects, we have to fix the Expire date. - if ((part.Flags & PrimFlags.TemporaryOnRez) != 0) part.ResetExpire(); + if ((part.Flags & PrimFlags.TemporaryOnRez) != 0) + part.ResetExpire(); return part; } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index a60ee9b..e06a222 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -53,19 +53,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// /// Deserialize a scene object from the original xml format /// - /// + /// /// - public static SceneObjectGroup FromOriginalXmlFormat(string serialization) - { - return FromOriginalXmlFormat(UUID.Zero, serialization); - } - - /// - /// Deserialize a scene object from the original xml format - /// - /// - /// - public static SceneObjectGroup FromOriginalXmlFormat(UUID fromUserInventoryItemID, string xmlData) + public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; @@ -87,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization sr = new StringReader(parts[0].InnerXml); reader = new XmlTextReader(sr); - SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); + SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); reader.Close(); sr.Close(); -- cgit v1.1 From 26b471f25a27d7e888d31854a3437f85191538a7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 22:28:27 +0100 Subject: Go back to resetting the State parameter for all parts of a SOG when SOG.ClearPartAttachmentData() is called. Even though we don't use these on rez they are still present after an unlink, after which selecting them causes various viewers to crash Hopefully really does address http://opensimulator.org/mantis/view.php?id=5664 --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 13 ++++++++----- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 6 ++++++ 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e6b58b3..4b39341 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -794,14 +794,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); } - // If it's rezzed in world, select it. Much easier to - // find small items. - // if (!attachment) { + // If it's rezzed in world, select it. Much easier to + // find small items. + // group.RootPart.CreateSelected = true; - foreach (SceneObjectPart child in group.Parts) - child.CreateSelected = true; + + foreach (SceneObjectPart part in group.Parts) + { + part.CreateSelected = true; + } } group.ResetIDs(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fca42c8..2819545 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -183,6 +183,12 @@ namespace OpenSim.Region.Framework.Scenes public void ClearPartAttachmentData() { AttachmentPoint = 0; + + // Even though we don't use child part state parameters for attachments any more, we still need to set + // these to zero since having them non-zero in rezzed scene objects will crash some clients. Even if + // we store them correctly, scene objects that we receive from elsewhere might not. + foreach (SceneObjectPart part in Parts) + part.Shape.State = 0; } /// -- cgit v1.1 From dbcfb25a52282a4cde84a770d4d9894b00c2c8b8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 22:54:03 +0100 Subject: Remove redundant RootPart.CreatedSelected = true in IAM.RezObject() since this is done through parts iteration --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 4b39341..0c0b0c5 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -799,8 +799,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // If it's rezzed in world, select it. Much easier to // find small items. // - group.RootPart.CreateSelected = true; - foreach (SceneObjectPart part in group.Parts) { part.CreateSelected = true; -- cgit v1.1 From e6eb0d9a6f2c0e792e3c1a77990fe18e153e454d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 2 Sep 2011 23:19:27 +0100 Subject: Comment out Scene.CleanDroppedAttachments() and calls. This method wasn't actually doing anything since dropped attachments retain a PCode of 9. Also, behaviour of dropped attachments in other places appears to be that they persist after avatar logout rather than get deleted. --- .../EntityTransfer/EntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 72 +++++++++++----------- 2 files changed, 37 insertions(+), 37 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 766656c..45506ed 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -493,7 +493,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Now let's make it officially a child agent sp.MakeChildAgent(); - sp.Scene.CleanDroppedAttachments(); +// sp.Scene.CleanDroppedAttachments(); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9794a34..d3de37d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3182,7 +3182,7 @@ namespace OpenSim.Region.Framework.Scenes } m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); - CleanDroppedAttachments(); +// CleanDroppedAttachments(); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); } @@ -3406,7 +3406,7 @@ namespace OpenSim.Region.Framework.Scenes if (vialogin) { - CleanDroppedAttachments(); +// CleanDroppedAttachments(); if (TestBorderCross(agent.startpos, Cardinals.E)) { @@ -5123,40 +5123,40 @@ namespace OpenSim.Region.Framework.Scenes } } - public void CleanDroppedAttachments() - { - List objectsToDelete = - new List(); - - lock (m_cleaningAttachments) - { - ForEachSOG(delegate (SceneObjectGroup grp) - { - if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) - { - UUID agentID = grp.OwnerID; - if (agentID == UUID.Zero) - { - objectsToDelete.Add(grp); - return; - } - - ScenePresence sp = GetScenePresence(agentID); - if (sp == null) - { - objectsToDelete.Add(grp); - return; - } - } - }); - } - - foreach (SceneObjectGroup grp in objectsToDelete) - { - m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); - DeleteSceneObject(grp, true); - } - } +// public void CleanDroppedAttachments() +// { +// List objectsToDelete = +// new List(); +// +// lock (m_cleaningAttachments) +// { +// ForEachSOG(delegate (SceneObjectGroup grp) +// { +// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) +// { +// UUID agentID = grp.OwnerID; +// if (agentID == UUID.Zero) +// { +// objectsToDelete.Add(grp); +// return; +// } +// +// ScenePresence sp = GetScenePresence(agentID); +// if (sp == null) +// { +// objectsToDelete.Add(grp); +// return; +// } +// } +// }); +// } +// +// foreach (SceneObjectGroup grp in objectsToDelete) +// { +// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); +// DeleteSceneObject(grp, true); +// } +// } // This method is called across the simulation connector to // determine if a given agent is allowed in this region -- cgit v1.1 From 5c1fa968ab954bec9860023dffc8f68baf3c0620 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 3 Sep 2011 01:11:16 +0100 Subject: Stop NPCs losing attachments when the source avatar takes them off. This was happening because we were using the source avatar's item IDs in the clone appearance. Switch to using the asset IDs of attachments instead for NPCs. The InventoryAccessModule and AttachmentModule had to be changed to allow rezzing of an object without an associated inventory item. Hopefully goes some way towards resolving http://opensimulator.org/mantis/view.php?id=5653 --- .../Avatar/Attachments/AttachmentsModule.cs | 76 ++++++++++++++-------- .../InventoryAccess/InventoryAccessModule.cs | 67 ++++++++++--------- .../Framework/Interfaces/IInventoryAccessModule.cs | 56 ++++++++++++++-- .../Region/Framework/Interfaces/IScenePresence.cs | 5 ++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 - 5 files changed, 140 insertions(+), 67 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ffe76a8..4881499 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -111,10 +111,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments List attachments = sp.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { - int p = attach.AttachPoint; - UUID itemID = attach.ItemID; + uint p = (uint)attach.AttachPoint; + +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}", +// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName); - //UUID assetID = attach.AssetID; // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down // But they're not used anyway, the item is being looked up for now, so let's proceed. //if (UUID.Zero == assetID) @@ -125,7 +127,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments try { - RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, (uint)p); + // If we're an NPC then skip all the item checks and manipulations since we don't have an + // inventory right now. + if (sp.PresenceType == PresenceType.Npc) + RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); + else + RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p); } catch (Exception e) { @@ -231,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return AttachObject(sp, group, AttachmentPt, silent); } - private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) + private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", @@ -284,17 +291,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments List attachments = sp.GetAttachments(attachmentPt); // At the moment we can only deal with a single attachment - if (attachments.Count != 0) - itemID = attachments[0].GetFromItemID(); - - if (itemID != UUID.Zero) - DetachSingleAttachmentToInv(itemID, sp); - - itemID = group.GetFromItemID(); - if (itemID == UUID.Zero) - itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; - - ShowAttachInUserInventory(sp, attachmentPt, itemID, group); + // We also don't want to do any of the inventory operations for an NPC. + if (sp.PresenceType != PresenceType.Npc) + { + if (attachments.Count != 0) + itemID = attachments[0].GetFromItemID(); + + if (itemID != UUID.Zero) + DetachSingleAttachmentToInv(itemID, sp); + + itemID = group.GetFromItemID(); + if (itemID == UUID.Zero) + itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; + + ShowAttachInUserInventory(sp, attachmentPt, itemID, group); + } AttachToAgent(sp, group, attachmentPt, attachPos, silent); @@ -312,7 +323,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + public ISceneEntity RezSingleAttachmentFromInventory( + IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); } @@ -338,7 +350,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // be removed when that functionality is implemented in opensim AttachmentPt &= 0x7f; - SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, AttachmentPt); + SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); if (updateInventoryStatus) { @@ -352,14 +364,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - ScenePresence sp, UUID itemID, uint attachmentPt) + IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) { - SceneObjectGroup objatt = invAccess.RezObject(sp.ControllingClient, - itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); + SceneObjectGroup objatt; + + if (itemID != UUID.Zero) + objatt = invAccess.RezObject(sp.ControllingClient, + itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + else + objatt = invAccess.RezObject(sp.ControllingClient, + null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", @@ -425,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// private UUID ShowAttachInUserInventory( - SceneObjectGroup att, ScenePresence sp, UUID itemID, uint attachmentPoint) + SceneObjectGroup att, IScenePresence sp, UUID itemID, uint attachmentPoint) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}", @@ -452,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// private void ShowAttachInUserInventory( - ScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) + IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) { // m_log.DebugFormat( // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", @@ -574,7 +593,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? - private void DetachSingleAttachmentToInv(UUID itemID, ScenePresence sp) + private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp) { if (itemID == UUID.Zero) // If this happened, someone made a mistake.... return; @@ -697,16 +716,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// Attach this scene object to the given avatar. /// - /// + /// /// This isn't publicly available since attachments should always perform the corresponding inventory /// operation (to show the attach in user inventory and update the asset with positional information). - /// + /// /// /// /// /// /// - protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) + private void AttachToAgent( + IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { // m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 0c0b0c5..4e8466d 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -669,28 +669,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return item; } - /// - /// Rez an object into the scene from the user's inventory - /// - /// - /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing - /// things to the scene. The caller should be doing that, I think. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The SceneObjectGroup rezzed or null if rez was unsuccessful. - public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, - UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, - bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) + public virtual SceneObjectGroup RezObject( + IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); @@ -707,13 +689,34 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } item.Owner = remoteClient.AgentId; - AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); + + return RezObject( + remoteClient, item, item.AssetID, + RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, + RezSelected, RemoveItem, fromTaskID, attachment); + } + + public virtual SceneObjectGroup RezObject( + IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) + { + AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); if (rezAsset == null) { - m_log.WarnFormat( - "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", - item.AssetID, item.Name, item.ID, remoteClient.Name); + if (item != null) + { + m_log.WarnFormat( + "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", + assetID, item.Name, item.ID, remoteClient.Name); + } + else + { + m_log.WarnFormat( + "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()", + assetID, remoteClient.Name); + } return null; } @@ -781,7 +784,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - if (!DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) + if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) return null; for (int i = 0; i < objlist.Count; i++) @@ -829,10 +832,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.AbsolutePosition = pos + veclist[i]; } - else - { - group.SetFromItemID(itemID); - } SceneObjectPart rootPart = group.RootPart; @@ -855,7 +854,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // group.Name, group.LocalId, group.UUID, remoteClient.Name); } - DoPostRezWhenFromItem(item, attachment); + if (item != null) + DoPostRezWhenFromItem(item, attachment); return group; } @@ -973,6 +973,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } rootPart.TrimPermissions(); + + if (isAttachment) + so.SetFromItemID(item.ID); } return true; diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index da11e61..1904011 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs @@ -54,10 +54,58 @@ namespace OpenSim.Region.Framework.Interfaces /// FIXME: This is not very useful. It would be far more useful to return a list of items instead. /// UUID CopyToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient); - - SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, - UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, - bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); + + /// + /// Rez an object into the scene from the user's inventory + /// + /// + /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing + /// things to the scene. The caller should be doing that, I think. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The SceneObjectGroup rezzed or null if rez was unsuccessful. + SceneObjectGroup RezObject( + IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); + + /// + /// Rez an object into the scene from the user's inventory + /// + /// + /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing + /// things to the scene. The caller should be doing that, I think. + /// + /// + /// + /// The item from which the object asset came. Can be null, in which case pre and post rez item adjustment and checks are not performed. + /// + /// The asset id for the object to rez. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The SceneObjectGroup rezzed or null if rez was unsuccessful. + SceneObjectGroup RezObject( + IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); + void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver); /// diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 91e4bf2..8913133 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -46,6 +46,11 @@ namespace OpenSim.Region.Framework.Interfaces IClientAPI ControllingClient { get; } /// + /// What type of presence is this? User, NPC, etc. + /// + PresenceType PresenceType { get; } + + /// /// Avatar appearance data. /// /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0d284a5..1c283c7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -75,9 +75,6 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// What type of presence is this? User, NPC, etc. - /// public PresenceType PresenceType { get; private set; } // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); -- cgit v1.1