From 9e68de6b8fd2362c00875633d26cddd33f6ea8ae Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 23 Nov 2010 13:32:46 -0800 Subject: [PATCH 01/15] PE physics plugin stubs --- .../ClientStack/LindenUDP/LLClientView.cs | 4 +- .../Region/Physics/PEPlugin/PECharacter.cs | 280 ++++++++++++++++++ OpenSim/Region/Physics/PEPlugin/PEPlugin.cs | 67 +++++ OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 277 +++++++++++++++++ OpenSim/Region/Physics/PEPlugin/PEScene.cs | 97 ++++++ OpenSim/Region/Physics/PEPlugin/Prop.cs | 46 +++ prebuild.xml | 29 ++ 7 files changed, 798 insertions(+), 2 deletions(-) create mode 100755 OpenSim/Region/Physics/PEPlugin/PECharacter.cs create mode 100755 OpenSim/Region/Physics/PEPlugin/PEPlugin.cs create mode 100755 OpenSim/Region/Physics/PEPlugin/PEPrim.cs create mode 100755 OpenSim/Region/Physics/PEPlugin/PEScene.cs create mode 100755 OpenSim/Region/Physics/PEPlugin/Prop.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index e1cbe03654..9f2b46e972 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -648,8 +648,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP catch (Exception e) { // Make sure that we see any exception caused by the asynchronous operation. - m_log.Error( - string.Format("[LLCLIENTVIEW]: Caught exception while processing {0}", packetObject.Pack), e); + m_log.ErrorFormat( "[LLCLIENTVIEW]: Caught exception while processing {0}: {1}", + packetObject.Pack, e.ToString()); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs new file mode 100755 index 0000000000..9cb43463ff --- /dev/null +++ b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs @@ -0,0 +1,280 @@ +/* + * Copyright (c) Intel Corporation + * + * 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 Intel Corporation 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.PEPlugin +{ +public class PECharacter : PhysicsActor +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool _stopped; + private Vector3 _size; + private PrimitiveBaseShape _pbs; + private uint _localID = 0; + private bool _grabbed; + private bool _selected; + private Vector3 _position; + private float _mass; + 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 bool _collidingGround; + private bool _collidingObj; + private bool _floatOnWater; + private Vector3 _rotationalVelocity; + private bool _kinematic; + private float _buoyancy; + + private Vector3 _PIDTarget; + private bool _usePID; + private float _PIDTau; + private bool _useHoverPID; + private float _PIDHoverHeight; + private PIDHoverType _PIDHoverType; + private float _PIDHoverTao; + + public PECharacter(String avName, PEScene parent_scene, Vector3 pos, + CollisionLocker dode, Vector3 size, float pid_d, float pid_p, + float capsule_radius, float tensor, float density, float height_fudge_factor, + float walk_divisor, float rundivisor) + { + return; + } + + public override bool Stopped { + get { return _stopped; } + } + public override Vector3 Size { + get { return _size; } + set { _size = value; + m_log.Debug("[PEE] PEChar set Size"); + Prop.Set(_localID, PropType.Size, _size); + } + } + public override PrimitiveBaseShape Shape { + set { _pbs = value; + m_log.Debug("[PEE] PEChar set Shape"); + Prop.Set(_localID, PropType.Shape, _pbs); + } + } + public override uint LocalID { + set { _localID = value; + m_log.Debug("[PEE] PEChar set LocalID"); + Prop.Set(_localID, PropType.LocalID, _localID); + } + } + public override bool Grabbed { + set { _grabbed = value; + m_log.Debug("[PEE] PEChar set Grabbed"); + Prop.Set(_localID, PropType.Grabbed, _grabbed); + } + } + public override bool Selected { + set { _selected = value; + m_log.Debug("[PEE] PEChar set Selected"); + Prop.Set(_localID, PropType.Selected, _selected); + } + } + 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 { return _position; } + set { _position = value; + // m_log.Debug("[PEE] PEChar set Position"); + Prop.Set(_localID, PropType.Position, _position); + } + } + public override float Mass { + get { return _mass; } + } + public override Vector3 Force { + get { return _force; } + set { _force = value; + m_log.Debug("[PEE] PEChar set Force"); + Prop.Set(_localID, PropType.Force, _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; + Prop.Set(_localID, PropType.Velocity, _velocity); + } + } + public override Vector3 Torque { + get { return _torque; } + set { _torque = value; + Prop.Set(_localID, PropType.Torque, _torque); + } + } + public override float CollisionScore { + get { return _collisionScore; } + set { _collisionScore = value; + Prop.Set(_localID, PropType.CollisionScore, _collisionScore); + } + } + public override Vector3 Acceleration { + get { return _acceleration; } + } + public override Quaternion Orientation { + get { return _orientation; } + set { _orientation = value; + Prop.Set(_localID, PropType.Orientation, _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; + } + } + 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 _isColliding; } + set { _isColliding = value; } + } + public override bool CollidingGround { + get { return _collidingGround; } + 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) { + } + public override void AddAngularForce(Vector3 force, bool pushforce) { + } + public override void SetMomentum(Vector3 momentum) { + } + public override void SubscribeEvents(int ms) { + } + public override void UnSubscribeEvents() { + } + public override bool SubscribedEvents() { + return false; + } + +} +} diff --git a/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs b/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs new file mode 100755 index 0000000000..1674b183f8 --- /dev/null +++ b/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) Intel Corporation + * + * 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 Intel Corporation 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.PEPlugin +{ +public class PEPlugin : IPhysicsPlugin +{ + //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private PEScene _mScene; + + public PEPlugin() + { + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene(String sceneIdentifier) + { + if (_mScene == null) + { + _mScene = new PEScene(sceneIdentifier); + } + return (_mScene); + } + + public string GetName() + { + return ("PhysicsEngineEngine"); + } + + public void Dispose() + { + } +} +} diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs new file mode 100755 index 0000000000..7d35d065b0 --- /dev/null +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -0,0 +1,277 @@ +/* + * Copyright (c) Intel Corporation + * + * 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 Intel Corporation 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 OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.PEPlugin +{ +public sealed class PEPrim : PhysicsActor +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool _stopped; + private Vector3 _size; + private PrimitiveBaseShape _pbs; + private uint _localID = 0; + private bool _grabbed; + private bool _selected; + private Vector3 _position; + private float _mass; + 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 bool _collidingGround; + private bool _collidingObj; + private bool _floatOnWater; + private Vector3 _rotationalVelocity; + private bool _kinematic; + private float _buoyancy; + + private Vector3 _PIDTarget; + private bool _usePID; + private float _PIDTau; + private bool _useHoverPID; + private float _PIDHoverHeight; + private PIDHoverType _PIDHoverType; + private float _PIDHoverTao; + + public PEPrim(String primName, PEScene parent_scene, Vector3 pos, Vector3 size, + Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) + { + // SendCreatePrim(primName, parent_scene, pos, size, rotation, mesh, pbs, pisPhysical, dode); + } + + public override bool Stopped { + get { return _stopped; } + } + public override Vector3 Size { + get { return _size; } + set { _size = value; + m_log.Debug("[PEE] PEPrim set Size"); + Prop.Set(_localID, PropType.Size, _size); + } + } + public override PrimitiveBaseShape Shape { + set { _pbs = value; + m_log.Debug("[PEE] PEPrim set Shape"); + Prop.Set(_localID, PropType.Shape, _pbs); + } + } + public override uint LocalID { + set { _localID = value; + m_log.Debug("[PEE] PEPrim set LocalID"); + Prop.Set(_localID, PropType.LocalID, _localID); + } + } + public override bool Grabbed { + set { _grabbed = value; + m_log.Debug("[PEE] PEPrim set Grabbed"); + Prop.Set(_localID, PropType.Grabbed, _grabbed); + } + } + public override bool Selected { + set { _selected = value; + m_log.Debug("[PEE] PEPrim set Selected"); + Prop.Set(_localID, PropType.Selected, _selected); + } + } + 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 { return _position; } + set { _position = value; + m_log.Debug("[PEE] PEPrim set Position"); + Prop.Set(_localID, PropType.Position, _position); + } + } + public override float Mass { + get { return _mass; } + } + public override Vector3 Force { + get { return _force; } + set { _force = value; + m_log.Debug("[PEE] PEPrim set Force"); + Prop.Set(_localID, PropType.Force, _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; + Prop.Set(_localID, PropType.Velocity, _velocity); + } + } + public override Vector3 Torque { + get { return _torque; } + set { _torque = value; + Prop.Set(_localID, PropType.Torque, _torque); + } + } + public override float CollisionScore { + get { return _collisionScore; } + set { _collisionScore = value; + Prop.Set(_localID, PropType.CollisionScore, _collisionScore); + } + } + public override Vector3 Acceleration { + get { return _acceleration; } + } + public override Quaternion Orientation { + get { return _orientation; } + set { _orientation = value; + Prop.Set(_localID, PropType.Orientation, _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; + } + } + 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 _isColliding; } + set { _isColliding = value; } + } + public override bool CollidingGround { + get { return _collidingGround; } + 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) { + } + public override void AddAngularForce(Vector3 force, bool pushforce) { + } + public override void SetMomentum(Vector3 momentum) { + } + public override void SubscribeEvents(int ms) { + } + public override void UnSubscribeEvents() { + } + public override bool SubscribedEvents() { + return false; + } +} +} diff --git a/OpenSim/Region/Physics/PEPlugin/PEScene.cs b/OpenSim/Region/Physics/PEPlugin/PEScene.cs new file mode 100755 index 0000000000..e47f06689e --- /dev/null +++ b/OpenSim/Region/Physics/PEPlugin/PEScene.cs @@ -0,0 +1,97 @@ +/* + * Copyright (c) Intel Corporation + * + * 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 Intel Corporation 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 Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.PEPlugin +{ +public class PEScene : PhysicsScene +{ + public PEScene(string identifier) + { + } + + public override void Initialise(IMesher meshmerizer, IConfigSource config) + { + } + + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) + { + PECharacter actor = new PECharacter(avName, this, position, null, size, 0f, 0f, .5f, 1f, + 1f, 1f, .5f, .5f); + return actor; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + } + + public override void RemovePrim(PhysicsActor prim) + { + } + + 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) + { + PEPrim prim = new PEPrim(primName, this, position, size, rotation, null, pbs, isPhysical, null); + return prim; + } + + public override void AddPhysicsActorTaint(PhysicsActor prim) { } + + public override float Simulate(float timeStep) + { + return 60f; // returns frames per second + } + + public override void GetResults() { } + + public override void SetTerrain(float[] heightMap) { } + + public override void SetWaterLevel(float baseheight) { } + + public override void DeleteTerrain() { } + + public override void Dispose() { } + + public override Dictionary GetTopColliders() + { + return new Dictionary(); + } + + public override bool IsThreaded { get { return false; } } + +} +} diff --git a/OpenSim/Region/Physics/PEPlugin/Prop.cs b/OpenSim/Region/Physics/PEPlugin/Prop.cs new file mode 100755 index 0000000000..8b68d69de6 --- /dev/null +++ b/OpenSim/Region/Physics/PEPlugin/Prop.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.PEPlugin +{ + public enum PropType + { + Size, + Shape, + LocalID, + Grabbed, + Selected, + Position, + Force, + Velocity, + Torque, + CollisionScore, + Orientation + }; + +public class Prop +{ + public static void Set(uint localID, PropType type, uint val) + { + } + public static void Set(uint localID, PropType type, Vector3 val) + { + } + public static void Set(uint localID, PropType type, PrimitiveBaseShape val) + { + } + public static void Set(uint localID, PropType type, bool val) + { + } + public static void Set(uint localID, PropType type, float val) + { + } + public static void Set(uint localID, PropType type, Quaternion val) + { + } + +} +} diff --git a/prebuild.xml b/prebuild.xml index c23770502b..5716295935 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -545,6 +545,35 @@ + + + + ../../../../bin/Physics/ + + + + + ../../../../bin/Physics/ + + + + ../../../../bin/ + + + + + + + + + + + + + + + + From b56b0c3086e62e4e8b8f749387cc77235f5d9584 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 1 Dec 2010 09:36:48 -0800 Subject: [PATCH 02/15] Initial plumbing for connectors and PhysActor discovery --- .../PhysEngineToSceneConnector.cs | 583 +++++++++++++ .../PhysEngineToSceneConnectorModule.cs | 796 ++++++++++++++++++ .../RegionSyncModule/RegionSyncMessage.cs | 3 +- .../SceneToPhysEngineConnector.cs | 393 +++++++++ .../SceneToPhysEngineSyncServer.cs | 480 +++++++++++ .../IPhysEngineToSceneConnectorModule.cs | 53 ++ OpenSim/Region/Framework/Scenes/Scene.cs | 44 +- .../Framework/Scenes/SceneObjectGroup.cs | 8 +- .../Framework/Scenes/SceneObjectPart.cs | 10 +- .../Region/Physics/Manager/PhysicsActor.cs | 14 +- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 2 + .../Region/Physics/PEPlugin/PECharacter.cs | 17 +- OpenSim/Region/Physics/PEPlugin/PEPlugin.cs | 2 +- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 17 +- OpenSim/Region/Physics/PEPlugin/PEScene.cs | 77 +- 15 files changed, 2468 insertions(+), 31 deletions(-) create mode 100644 OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs create mode 100644 OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs create mode 100644 OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs create mode 100644 OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs create mode 100755 OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs new file mode 100644 index 0000000000..11f71c699e --- /dev/null +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -0,0 +1,583 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using OpenMetaverse; +using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes.Types; +using log4net; + +using Nini.Config; + +namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule +{ + //The data structure that maintains the list of quarks a script engine subscribes to. + //It might be better to organize the quarks in a k-d tree structure, for easier + //partitioning of the quarks based on spatial information. + //But for now, we just assume the quarks each script engine operates on form a rectangle shape. + //So we just use xmin,ymin and xmax,ymax to identify the rectange; and use a List structure to + //store the quarks. + //Quark size is defined in QuarkInfo.SizeX and QuarkInfo.SizeY. + + // The RegionSyncPhysEngine has a receive thread to process messages from the RegionSyncServer. + // It is the client side of the synchronization channel, and send to and receive updates from the + // Auth. Scene. The server side thread handling the sync channel is implemented in RegionSyncScriptAPI.cs. + // + // The current implementation is very similar to RegionSyncClient. + // TODO: eventually the same RegionSyncSceneAPI should handle all traffic from different actors, e.g. + // using a pub/sub model. + public class PhysEngineToSceneConnector + { + #region PhysEngineToSceneConnector members + + // Set the addr and port of RegionSyncServer + private IPAddress m_addr; + private string m_addrString; + private Int32 m_port; + + // A reference to the local scene + private Scene m_validLocalScene; + + // The avatars added to this client manager for clients on other client managers + object m_syncRoot = new object(); + + // The logfile + private ILog m_log; + + private string LogHeader = "[PHYSICS ENGINE TO SCENE CONNECTOR]"; + + // The listener and the thread which listens for connections from client managers + private Thread m_rcvLoop; + + // The client connection to the RegionSyncServer + private TcpClient m_client = new TcpClient(); + + private string m_authSceneName; + + //KittyL: Comment out m_statsTimer for now, will figure out whether we need it for PhysEngine later + //private System.Timers.Timer m_statsTimer = new System.Timers.Timer(30000); + + // The queue of incoming messages which need handling + //private Queue m_inQ = new Queue(); + + //KittyL: added to identify different actors + private ActorType m_actorType = ActorType.PhysicsEngine; + + private bool m_debugWithViewer = false; + + private QuarkSubsriptionInfo m_subscribedQuarks; + + + private IConfig m_sysConfig; + + //members for load balancing purpose + //private TcpClient m_loadMigrationSouceEnd = null; + private LoadMigrationEndPoint m_loadMigrationSouceEnd = null; + private Thread m_loadMigrationSrcRcvLoop; + private LoadMigrationListener m_loadMigrationListener = null; + + //List of queued messages, when the space that the updated object is located is being migrated + private List m_updateMsgQueue = new List(); + + #endregion + + + // Constructor + public PhysEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, string authSceneName, IConfig sysConfig) + { + m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + m_validLocalScene = validLocalScene; + m_addr = IPAddress.Parse(addr); + m_addrString = addr; + m_port = port; + m_debugWithViewer = debugWithViewer; + m_authSceneName = authSceneName; + //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); + m_sysConfig = sysConfig; + + //assume we are connecting to the whole scene as one big quark + m_subscribedQuarks = new QuarkSubsriptionInfo(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); + } + + /// + /// Create a PhysEngineToSceneConnector based on the space it is supposed to subscribe (and operate) on. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public PhysEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, string authSceneName, + string subscriptionSpace, IConfig sysConfig) + { + if (QuarkInfo.SizeX == -1 || QuarkInfo.SizeY == -1) + { + m_log.Error("QuarkInfo.SizeX or QuarkInfo.SizeY has not been configured."); + Environment.Exit(0); + } + + m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + m_validLocalScene = validLocalScene; + m_addr = IPAddress.Parse(addr); + m_addrString = addr; + m_port = port; + m_debugWithViewer = debugWithViewer; + m_authSceneName = authSceneName; + //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); + m_sysConfig = sysConfig; + + m_subscribedQuarks = new QuarkSubsriptionInfo(subscriptionSpace); + } + + public PhysEngineToSceneConnectorModule GetPEToSceneConnectorMasterModule() + { + if (m_validLocalScene == null) + return null; + return (PhysEngineToSceneConnectorModule)m_validLocalScene.PhysEngineToSceneConnectorModule; + } + + public Scene GetValidLocalScene() + { + return m_validLocalScene; + } + + + private List GetQuarkStringList() + { + List quarkList = new List(); + foreach (QuarkInfo quark in m_subscribedQuarks.QuarkList) + { + quarkList.Add(quark.QuarkStringRepresentation); + } + return quarkList; + } + + + + /// + /// Get the reference to the local scene that is supposed to be mapped to the remote auth. scene. + /// + /// + /// + private Scene GetLocalScene(string authSceneName) + { + PhysEngineToSceneConnectorModule connectorModule = GetPEToSceneConnectorMasterModule(); + return connectorModule.GetLocalScene(authSceneName); + } + + // Start the RegionSyncPhysEngine client thread + public bool Start() + { + if (EstablishConnection()) + { + StartStateSync(); + return true; + } + else + { + return false; + } + } + + private bool EstablishConnection() + { + if (m_client.Connected) + { + m_log.Warn(LogHeader + ": already connected"); + return false; + } + + try + { + m_client.Connect(m_addr, m_port); + } + catch (Exception e) + { + m_log.WarnFormat("{0} [Start] Could not connect to SceneToPhysEngineSyncServer at {1}:{2}", LogHeader, m_addr, m_port); + m_log.Warn(e.Message); + return false; + } + + m_log.WarnFormat("{0} Connected to SceneToPhysEngineSyncServer at {1}:{2}", LogHeader, m_addr, m_port); + + m_rcvLoop = new Thread(new ThreadStart(ReceiveLoop)); + m_rcvLoop.Name = "PhysEngineToSceneConnector ReceiveLoop"; + m_log.WarnFormat("{0} Starting {1} thread", LogHeader, m_rcvLoop.Name); + m_rcvLoop.Start(); + return true; + } + + private void StartStateSync() + { + RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStatus, Convert.ToString((int)ActorStatus.Sync)); + Send(msg); + SendQuarkSubscription(); + Thread.Sleep(100); + DoInitialSync(); + } + + + private void SendQuarkSubscription() + { + List quarkStringList = GetQuarkStringList(); + string quarkString = RegionSyncUtil.QuarkStringListToString(quarkStringList); + + m_log.Debug(LogHeader + ": subscribe to quarks: " + quarkString); + //Send(quarkString); + RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.QuarkSubscription, quarkString); + Send(msg); + } + + public void SetQuarkSubscription(QuarkSubsriptionInfo quarks) + { + m_subscribedQuarks = quarks; + } + + public void RegisterIdle() + { + EstablishConnection(); + RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStatus, Convert.ToString((int)ActorStatus.Idle)); + Send(msg); + } + + private void DoInitialSync() + { + m_validLocalScene.DeleteAllSceneObjects(); + //m_log.Debug(LogHeader + ": send actor type " + m_actorType); + //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorType, Convert.ToString((int)m_actorType))); + //KittyL??? Do we need to send in RegionName? + + //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName)); + //m_log.WarnFormat("Sending region name: \"{0}\"", m_scene.RegionInfo.RegionName); + + Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain)); + Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects)); + + // Register for events which will be forwarded to authoritative scene + // m_scene.EventManager.OnNewClient += EventManager_OnNewClient; + //m_scene.EventManager.OnClientClosed += new EventManager.ClientClosed(RemoveLocalClient); + } + + // Disconnect from the RegionSyncServer and close client thread + public void Stop() + { + Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStop, "stop")); + // The remote scene will remove the SceneToPhysEngineConnector when we disconnect + m_rcvLoop.Abort(); + ShutdownClient(); + + //stop the migration connections + //ShutdownClient(m_loadMigrationSouceEnd); + if (m_loadMigrationListener != null) + m_loadMigrationListener.Shutdown(); + } + + public void ReportStatus() + { + m_log.WarnFormat("{0} Synchronized to RegionSyncServer at {1}:{2}", LogHeader, m_addr, m_port); + lock (m_syncRoot) + { + //TODO: should be reporting about the information of the objects/scripts + } + } + + private void ShutdownClient() + { + m_log.WarnFormat("{0} Disconnected from RegionSyncServer. Shutting down.", LogHeader); + + //TODO: remove the objects and scripts + //lock (m_syncRoot) + //{ + + //} + + if (m_client != null) + { + // Close the connection + m_client.Client.Close(); + m_client.Close(); + } + + } + + // Listen for messages from a RegionSyncServer + // *** This is the main thread loop for each connected client + private void ReceiveLoop() + { + m_log.WarnFormat("{0} Thread running: {1}", LogHeader, m_rcvLoop.Name); + while (true && m_client.Connected) + { + RegionSyncMessage msg; + // Try to get the message from the network stream + try + { + msg = new RegionSyncMessage(m_client.GetStream()); + //m_log.WarnFormat("{0} Received: {1}", LogHeader, msg.ToString()); + } + // If there is a problem reading from the client, shut 'er down. + catch + { + ShutdownClient(); + return; + } + // Try handling the message + try + { + //lock (m_syncRoot) -- KittyL: why do we need to lock here? We could lock inside HandleMessage if necessary, and lock on different objects for better performance + HandleMessage(msg); + } + catch (Exception e) + { + m_log.WarnFormat("{0} Encountered an exception: {1} (MSGTYPE = {2})", LogHeader, e.Message, msg.ToString()); + } + } + } + + #region SEND + //DSG-TODO: for Scene based DSG, Send() also needs to figure out which Scene to send to, e.g. needs a switching function based on object position + + // Send a message to a single connected RegionSyncServer + private void Send(string msg) + { + byte[] bmsg = System.Text.Encoding.ASCII.GetBytes(msg + System.Environment.NewLine); + Send(bmsg); + } + + private void Send(RegionSyncMessage msg) + { + Send(msg.ToBytes()); + //m_log.WarnFormat("{0} Sent {1}", LogHeader, msg.ToString()); + } + + private void Send(byte[] data) + { + if (m_client.Connected) + { + try + { + m_client.GetStream().Write(data, 0, data.Length); + } + // If there is a problem reading from the client, shut 'er down. + // *** Still need to alert the module that it's no longer connected! + catch + { + ShutdownClient(); + } + } + } + + /// + /// Send requests to update object properties in the remote authoratative Scene. + /// + /// UUID of the object + /// name of the property to be updated + /// parameters of the value of the property + /// + public void SendSetPrimProperties(UUID primID, string pName, object val) + { + OSDMap data = new OSDMap(); + data["UUID"] = OSD.FromUUID(primID); + data["name"] = OSD.FromString(pName); + object[] valParams = (object[])val; + //data["param"] = OSD.FromString(presence.ControllingClient.LastName); + Vector3 pos, vel; + switch (pName) + { + case "object_rez": + //this is to rez an object from the prim's inventory, rather than change the prim's property + if(valParams.Length<5){ + m_log.Warn(LogHeader+": values for object's "+pName+" property should include: inventory, pos, velocity, rotation, param"); + return; + } + string inventory = (string)valParams[0]; + pos = (Vector3)valParams[1]; + vel = (Vector3)valParams[2]; + Quaternion rot = (Quaternion)valParams[3]; + int param = (int)valParams[4]; + data["inventory"]=OSD.FromString(inventory); + data["pos"]=OSD.FromVector3(pos); + data["vel"] = OSD.FromVector3(vel); + data["rot"] = OSD.FromQuaternion(rot); + data["param"] = OSD.FromInteger(param); + break; + case "color": + if(valParams.Length<2){ + m_log.Warn(LogHeader+": values for object's "+pName+" property should include: color-x, color-y, color-z, face"); + return; + } + //double cx = (double)valParams[0]; + //double cy = (double)valParams[1]; + //double cz = (double)valParams[2]; + //Vector3 color = new Vector3((float)cx, (float)cy, (float)cz); + Vector3 color = (Vector3)valParams[0]; + data["color"] = OSD.FromVector3(color); + data["face"] = OSD.FromInteger((int)valParams[1]); + + //m_log.DebugFormat("{0}: to set color {1} on face {2} of prim {3}", LogHeader, color.ToString(), (int)valParams[1], primID); + + break; + case "pos": + if (valParams.Length < 1) + { + m_log.Warn(LogHeader + ": values for object's " + pName + " property should include: pos(vector)"); + return; + } + //double px = (double)valParams[0]; + //double py = (double)valParams[1]; + //double pz = (double)valParams[2]; + //Vector3 pos = new Vector3((float)px, (float)py, (float)pz); + pos = (Vector3)valParams[0]; + data["pos"] = OSD.FromVector3(pos); + + m_log.DebugFormat("{0}: to set pos {1} for prim {2}", LogHeader, pos.ToString(), primID); + break; + default: + // + break; + } + + Send(new RegionSyncMessage(RegionSyncMessage.MsgType.SetObjectProperty, OSDParser.SerializeJsonString(data))); + } + #endregion SEND + + //KittyL: Has to define SendCoarseLocations() here, since it's defined in IRegionSyncClientModule. + // But should not do much as being PhysEngine, not ClientManager + public void SendCoarseLocations() + { + } + + // Handle an incoming message + // Dan-TODO: This should not be synchronous with the receive! + // Instead, handle messages from an incoming Queue so server doesn't block sending + // + // KittyL: This is the function that PhysEngine and ClientManager have the most different implementations + private void HandleMessage(RegionSyncMessage msg) + { + //TO FINISH: + + switch (msg.Type) + { + case RegionSyncMessage.MsgType.RegionName: + { + string authSceneName = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + if (authSceneName != m_authSceneName) + { + //This should not happen. If happens, check the configuration files (OpenSim.ini) on other sides. + m_log.Warn(": !!! Mismatch between configurations of authoritative scene. Script Engine's config: "+m_authSceneName+", Scene's config: "+authSceneName); + return; + } + RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_authSceneName)); + return; + } + case RegionSyncMessage.MsgType.Terrain: + { + //We need to handle terrain differently as we handle objects: we really will set the HeightMap + //of each local scene that is the shadow copy of its auth. scene. + Scene localScene = GetLocalScene(m_authSceneName); + if (localScene == null) + { + m_log.Warn("no local Scene mapped to "+m_authSceneName); + return; + } + localScene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); + RegionSyncMessage.HandleSuccess(LogHeader, msg, "Synchronized terrain"); + return; + } + case RegionSyncMessage.MsgType.NewObject: + case RegionSyncMessage.MsgType.UpdatedObject: + { + HandleAddOrUpdateObjectInLocalScene(msg); + return; + } + default: + { + RegionSyncMessage.HandleError(LogHeader, msg, String.Format("{0} Unsupported message type: {1}", LogHeader, ((int)msg.Type).ToString())); + return; + } + } + + } + + #region Utility functions + + private OSDMap GetOSDMap(string strdata) + { + OSDMap args = null; + OSD buffer = OSDParser.DeserializeJson(strdata); + if (buffer.Type == OSDType.Map) + { + args = (OSDMap)buffer; + return args; + } + return null; + + } + + HashSet exceptions = new HashSet(); + private OSDMap DeserializeMessage(RegionSyncMessage msg) + { + OSDMap data = null; + try + { + data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap; + } + catch (Exception e) + { + lock (exceptions) + // If this is a new message, then print the underlying data that caused it + if (!exceptions.Contains(e.Message)) + m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); + data = null; + } + return data; + } + + + + public string GetServerAddressAndPort() + { + return m_addr.ToString() + ":" + m_port.ToString(); + } + + #endregion Utility functions + + #region Handlers for Scene events + + private void HandleAddOrUpdateObjectInLocalScene(RegionSyncMessage msg) + { + // TODO: modify for physics + OSDMap data = DeserializeMessage(msg); + /* + if (data["locX"] == null || data["locY"] == null || data["sogXml"] == null) + { + m_log.Warn(LogHeader + ": parameters missing in NewObject/UpdatedObject message, need to have locX, locY, sogXml"); + return; + } + * */ + uint locX = data["locX"].AsUInteger(); + uint locY = data["locY"].AsUInteger(); + string sogxml = data["sogXml"].AsString(); + SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); + + } + + #endregion Handlers for events/updates from Scene + + } + +} diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs new file mode 100644 index 0000000000..8ea8bd6fb6 --- /dev/null +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -0,0 +1,796 @@ +/* + * 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 OpenSim 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 Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Client; +using OpenSim.Region.CoreModules.Framework.InterfaceCommander; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using log4net; +using System.Net; +using System.Net.Sockets; + +namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule +{ + //The connector that connects the local Scene (cache) and remote authoratative Scene + public class PhysEngineToSceneConnectorModule : IRegionModule, IPhysEngineToSceneConnectorModule, ICommandableModule + { + #region IRegionModule Members + + public void Initialise(Scene scene, IConfigSource config) + { + m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + m_active = false; //set to false unless this is the valid local scene + + //Read in configuration + IConfig syncConfig = config.Configs["RegionSyncModule"]; + if (syncConfig != null && syncConfig.GetString("Enabled", "").ToLower() == "true") + { + scene.RegionSyncEnabled = true; + } + else + { + scene.RegionSyncEnabled = false; + } + + m_regionSyncMode = syncConfig.GetString("Mode", "").ToLower(); + if (syncConfig == null || m_regionSyncMode != "physics_engine") + { + m_log.Warn("[REGION SYNC PHYSICS ENGINE MODULE] Not in script_engine mode. Shutting down."); + return; + } + + //get the name of the valid region for script engine, i.e., that region that will holds all objects and scripts + //if not matching m_scene's name, simply return + string validLocalScene = syncConfig.GetString("ValidPhysEngineScene", ""); + if (!validLocalScene.Equals(scene.RegionInfo.RegionName)) + { + m_log.Warn("Not the valid local scene, shutting down"); + return; + } + m_active = true; + m_validLocalScene = validLocalScene; + + m_log.Debug("Init PEToSceneConnectorModule, for local scene " + scene.RegionInfo.RegionName); + + //get the number of regions this script engine subscribes + m_sceneNum = syncConfig.GetInt("SceneNumber", 1); + + //get the mapping of local scenes to auth. scenes + List authScenes = new List(); + for (int i = 0; i < m_sceneNum; i++) + { + string localScene = "LocalScene" + i; + string localSceneName = syncConfig.GetString(localScene, ""); + string masterScene = localScene + "Master"; + string masterSceneName = syncConfig.GetString(masterScene, ""); + + if (localSceneName.Equals("") || masterSceneName.Equals("")) + { + m_log.Warn(localScene + " or " + masterScene+ " has not been assigned a value in configuration. Shutting down."); + return; + } + + //m_localToAuthSceneMapping.Add(localSceneName, masterSceneName); + RecordLocalAuthSceneMappings(localSceneName, masterSceneName); + authScenes.Add(masterSceneName); + m_localScenesByName.Add(localSceneName, null); + } + + int defaultPort = 13000; + //get the addr:port info of the authoritative scenes + for (int i = 0; i < m_sceneNum; i++) + { + string authSceneName = authScenes[i]; + //string serverAddr = authSceneName + "_ServerIPAddress"; + //string serverPort = authSceneName + "_ServerPort"; + string serverAddr = authSceneName + "_SceneToPESyncServerIP"; + string addr = syncConfig.GetString(serverAddr, "127.0.0.1"); + string serverPort = authSceneName + "_SceneToPESyncServerPort"; + int port = syncConfig.GetInt(serverPort, defaultPort); + defaultPort++; + + AuthSceneInfo authSceneInfo = new AuthSceneInfo(authSceneName, addr, port); + m_authScenesInfoByName.Add(authSceneName, authSceneInfo); + } + + m_scene = scene; + m_scene.RegisterModuleInterface(this); + m_syncConfig = syncConfig; + m_debugWithViewer = syncConfig.GetBoolean("PhysEngineDebugWithViewer", false); + + //read in the quark size information + //QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); + //QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); + QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); + QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); + + //m_quarkListString = syncConfig.GetString("InitQuarkSet", ""); //if not specified, dost not subscribe to any quark + //if (m_quarkListString.Equals("all")) + //{ + // m_quarkListString = RegionSyncUtil.QuarkStringListToString(RegionSyncUtil.GetAllQuarkStringInScene(QuarkInfo.SizeX, QuarkInfo.SizeY)); + //} + m_subscriptionSpaceString = syncConfig.GetString("InitSubscriptionSpace", "0_0,256_256"); + + + // Setup the command line interface + m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; + InstallInterfaces(); + + m_log.Warn("[REGION SYNC PHYSICS ENGINE MODULE] Initialised"); + } + + public void PostInitialise() + { + if (!m_active) + return; + + //m_log.Warn("[REGION SYNC CLIENT MODULE] Post-Initialised"); + m_scene.EventManager.OnPopulateLocalSceneList += OnPopulateLocalSceneList; + } + + public void Close() + { + if (m_active) + { + m_scene.EventManager.OnPopulateLocalSceneList -= OnPopulateLocalSceneList; + } + m_scene = null; + m_active = false; + } + + public string Name + { + get { return "RegionSyncPhysEngineModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + #endregion + + #region ICommandableModule Members + private readonly Commander m_commander = new Commander("sync"); + public ICommander CommandInterface + { + get { return m_commander; } + } + #endregion + + #region IPhysEngineToSceneConnectorModule members + + + public bool Active + { + get { return m_active; } + } + + public bool Synced + { + get + { + lock(m_client_lock) + { + return (m_PEToSceneConnectors.Count > 0); + } + } + } + + + #endregion + + #region PhysEngineToSceneConnectorModule members and functions + + private bool m_active = false; + private string m_serveraddr; + private int m_serverport; + private Scene m_scene; + private ILog m_log; + private Object m_client_lock = new Object(); + //private PhysEngineToSceneConnector m_scriptEngineToSceneConnector = null; + private IConfig m_syncConfig = null; + private bool m_debugWithViewer = false; + private string m_regionSyncMode = ""; + + //Variables relavant for multi-scene subscription. + private int m_sceneNum = 0; + private string m_validLocalScene = ""; + private Dictionary m_localToAuthSceneMapping = new Dictionary(); //1-1 mapping from local shadow scene to authoratative scene + private Dictionary m_authToLocalSceneMapping = new Dictionary(); //1-1 mapping from authoratative scene to local shadow scene + private Dictionary m_localScenesByName = new Dictionary(); //name and references to local scenes + private Dictionary m_authScenesInfoByName = new Dictionary(); //info of each auth. scene's connector port, stored by each scene's name + private Dictionary m_PEToSceneConnectors = new Dictionary(); //connector for each auth. scene + private Dictionary m_authScenesInfoByLoc = new Dictionary(); //IP and port number of each auth. scene's connector port + private string LogHeader = "[PhysEngineToSceneConnectorModule]"; + private PhysEngineToSceneConnector m_idlePEToSceneConnector = null; + + //quark information + //private int QuarkInfo.SizeX; + //private int QuarkInfo.SizeY; + //private string m_quarkListString; + private string m_subscriptionSpaceString; + + public IConfig SyncConfig + { + get { return m_syncConfig; } + } + + public bool DebugWithViewer + { + get { return m_debugWithViewer; } + } + + //Record the locX and locY of one auth. scene (identified by addr:port) this PhysEngine connects to + public void RecordSceneLocation(string addr, int port, uint locX, uint locY) + { + string loc = SceneLocToString(locX, locY); + if (m_authScenesInfoByLoc.ContainsKey(loc)) + { + m_log.Warn(": have already registered info for Scene at " + loc); + m_authScenesInfoByLoc.Remove(loc); + } + + foreach (KeyValuePair valPair in m_authScenesInfoByName) + { + AuthSceneInfo authSceneInfo = valPair.Value; + if (authSceneInfo.Addr == addr && authSceneInfo.Port == port) + { + authSceneInfo.LocX = (int)locX; + authSceneInfo.LocY = (int)locY; + m_authScenesInfoByLoc.Add(loc, authSceneInfo); + break; + } + } + } + + /// + /// Set the property of a prim located in the given scene (identified by locX, locY) + /// + /// + /// + /// + /// + /// + public void SendSetPrimProperties(uint locX, uint locY, UUID primID, string pName, object pValue) + { + if (!Active || !Synced) + return; + + PhysEngineToSceneConnector connector = GetPEToSceneConnector(locX, locY); + connector.SendSetPrimProperties(primID, pName, pValue); + } + + public Scene GetLocalScene(string authSceneName) + { + if (!m_authToLocalSceneMapping.ContainsKey(authSceneName)) + { + m_log.Warn(LogHeader + ": no authoritative scene with name "+authSceneName+" recorded"); + return null; + } + string localSceneName = m_authToLocalSceneMapping[authSceneName]; + if (m_localScenesByName.ContainsKey(localSceneName)) + { + return m_localScenesByName[localSceneName]; + } + else + return null; + } + + private string SceneLocToString(uint locX, uint locY) + { + string loc = locX + "-" + locY; + return loc; + } + + //Get the right instance of PhysEngineToSceneConnector, given the location of the authoritative scene + private PhysEngineToSceneConnector GetPEToSceneConnector(uint locX, uint locY) + { + string loc = SceneLocToString(locX, locY); + if (!m_authScenesInfoByLoc.ContainsKey(loc)) + return null; + string authSceneName = m_authScenesInfoByLoc[loc].Name; + if (!m_PEToSceneConnectors.ContainsKey(authSceneName)) + { + return null; + } + return m_PEToSceneConnectors[authSceneName]; + } + + + private void RecordLocalAuthSceneMappings(string localSceneName, string authSceneName) + { + if (m_localToAuthSceneMapping.ContainsKey(localSceneName)) + { + m_log.Warn(LogHeader + ": already registered " + localSceneName+", authScene was recorded as "+ m_localToAuthSceneMapping[localSceneName]); + } + else + { + m_localToAuthSceneMapping.Add(localSceneName, authSceneName); + } + if (m_authToLocalSceneMapping.ContainsKey(authSceneName)) + { + m_log.Warn(LogHeader + ": already registered " + authSceneName + ", authScene was recorded as " + m_authToLocalSceneMapping[authSceneName]); + } + else + { + m_authToLocalSceneMapping.Add(authSceneName, localSceneName); + } + } + + //Get the name of the authoritative scene the given local scene maps to. Return null if not found. + private string GetAuthSceneName(string localSceneName) + { + if (m_localToAuthSceneMapping.ContainsKey(localSceneName)) + { + m_log.Warn(LogHeader + ": " + localSceneName + " not registered in m_localToAuthSceneMapping"); + return null; + } + return m_localToAuthSceneMapping[localSceneName]; + } + + //get the name of the local scene the given authoritative scene maps to. Return null if not found. + private string GetLocalSceneName(string authSceneName) + { + if (!m_authToLocalSceneMapping.ContainsKey(authSceneName)) + { + m_log.Warn(LogHeader + ": " + authSceneName + " not registered in m_authToLocalSceneMapping"); + return null; + } + return m_authToLocalSceneMapping[authSceneName]; + } + + #endregion + + #region Event Handlers + + public void OnPopulateLocalSceneList(List localScenes) + //public void OnPopulateLocalSceneList(List localScenes, string[] cmdparams) + { + if (!Active) + return; + + //populate the dictionary m_localScenes + foreach (Scene lScene in localScenes) + { + string name = lScene.RegionInfo.RegionName; + if(!m_localScenesByName.ContainsKey(name)){ + m_log.Warn(LogHeader+": has not reigstered a local scene named "+name); + continue; + } + m_localScenesByName[name] = lScene; + + //lScene.RegionSyncMode = m_regionSyncMode; + lScene.IsOutsideScenes = IsOutSideSceneSubscriptions; + } + + //test position conversion + /* + //Vector3 pos = new Vector3(290, 100, 10); + uint preLocX = Convert.ToUInt32(cmdparams[2]); + uint preLocY = Convert.ToUInt32(cmdparams[3]); + float posX = (float)Convert.ToDouble(cmdparams[4]); + float posY = (float)Convert.ToDouble(cmdparams[5]); + float posZ = (float)Convert.ToDouble(cmdparams[6]); + Vector3 pos = new Vector3(posX, posY, posZ); + uint locX, locY; + Vector3 newPos; + ConvertPosition(1000, 1000, pos, out locX, out locY, out newPos); + * */ + } + + #endregion + + private string GetAllSceneNames() + { + string scenes = ""; + foreach (KeyValuePair valPair in m_localScenesByName) + { + Scene lScene = valPair.Value; + string authScene = m_localToAuthSceneMapping[lScene.RegionInfo.RegionName]; + scenes += authScene + ","; + + } + return scenes; + } + + //public bool IsOutSideSceneSubscriptions(Scene currentScene, Vector3 pos) + public bool IsOutSideSceneSubscriptions(uint locX, uint locY, Vector3 pos) + { + string sceneNames = GetAllSceneNames(); + m_log.Debug(LogHeader + ": IsOutSideSceneSubscriptions called. Conceptually, we are checking inside scene-subscriptions: " + sceneNames); + + //First, convert the position to a scene s.t. the attempting position is contained withing that scene + uint curLocX, curLocY; + Vector3 curPos; + bool converted = ConvertPosition(locX, locY, pos, out curLocX, out curLocY, out curPos); + + if (!converted) + { + m_log.Warn("("+locX+","+locY+","+pos+")"+" converts to scenes with negative coordinates."); + return false; + } + //See of the quark identified by (curLocX,curLocY) is one we subscribed to + string sceneLoc = SceneLocToString(curLocX, curLocY); + if (m_authScenesInfoByLoc.ContainsKey(sceneLoc)) + { + return false; + } + else + { + return true; + } + } + + //When the offset position is outside the range of current scene, convert it to the offset position in the right quark. + //Return null if the new scene's left-bottom corner X or Y value is negative. + //Assumption: A position is uniquely identified by (locX, locY, offsetPos). + private bool ConvertPosition(uint preLocX, uint preLocY, Vector3 prePos, out uint curLocX, out uint curLocY, out Vector3 curPos) + { + Vector3 newPos; + int newLocX; + int newLocY; + //code copied from EntityTransferModule.Cross() + + newPos = prePos; + newLocX = (int)preLocX; + newLocY = (int)preLocY; + + int changeX = 1; + int changeY = 1; + + //Adjust the X values, if going east, changeX is positive, otherwise, it is negative + if (prePos.X >= 0) + { + changeX = (int)(prePos.X / (int)Constants.RegionSize); + } + else + { + changeX = (int)(prePos.X / (int)Constants.RegionSize) - 1 ; + } + newLocX = (int)preLocX + changeX; + newPos.X = prePos.X - (changeX * Constants.RegionSize); + + if (prePos.Y >= 0) + { + changeY = (int)(prePos.Y / (int)Constants.RegionSize); + } + else + { + changeY = (int)(prePos.Y / (int)Constants.RegionSize) - 1; + } + changeY = (int)(prePos.Y / (int)Constants.RegionSize); + newLocY = (int)preLocY + changeY; + newPos.Y = prePos.Y - (changeY * Constants.RegionSize); + + curLocX = (uint)newLocX; + curLocY = (uint)newLocY; + curPos = newPos; + + if (newLocX < 0 || newLocY < 0) + { + //reset the position + curLocX = preLocX; + curLocY = preLocY; + if (newLocX < 0) + { + curPos.X = 2; + } + if(newLocY<0) + { + curPos.Y = 2; + } + return false; + } + else + return true; + } + + + private void DebugSceneStats() + { + return; + /* + List avatars = m_scene.GetAvatars(); + List entities = m_scene.GetEntities(); + m_log.WarnFormat("There are {0} avatars and {1} entities in the scene", avatars.Count, entities.Count); + */ + } + + #region Console Command Interface + //IMPORTANT: these functions should only be actived for the PhysEngineToSceneConnectorModule that is associated with the valid local scene + + private void InstallInterfaces() + { + Command cmdSyncStart = new Command("start", CommandIntentions.COMMAND_HAZARDOUS, SyncStart, "Begins synchronization with RegionSyncServer."); + //cmdSyncStart.AddArgument("server_port", "The port of the server to synchronize with", "Integer"); + + Command cmdSyncStop = new Command("stop", CommandIntentions.COMMAND_HAZARDOUS, SyncStop, "Stops synchronization with RegionSyncServer."); + //cmdSyncStop.AddArgument("server_address", "The IP address of the server to synchronize with", "String"); + //cmdSyncStop.AddArgument("server_port", "The port of the server to synchronize with", "Integer"); + + Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status."); + + //The following two commands are more for easier debugging purpose + Command cmdSyncSetQuarks = new Command("quarkSpace", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkList, "Set the set of quarks to subscribe to. For debugging purpose. Should be issued before \"sync start\""); + cmdSyncSetQuarks.AddArgument("quarkSpace", "The (rectangle) space of quarks to subscribe, represented by x0_y0,x1_y1, the left-bottom and top-right corners of the rectangel space", "String"); + + Command cmdSyncSetQuarkSize = new Command("quarksize", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkSize, "Set the size of each quark. For debugging purpose. Should be issued before \"sync quarks\""); + cmdSyncSetQuarkSize.AddArgument("quarksizeX", "The size on x axis of each quark", "Integer"); + cmdSyncSetQuarkSize.AddArgument("quarksizeY", "The size on y axis of each quark", "Integer"); + + Command cmdSyncRegister = new Command("register", CommandIntentions.COMMAND_HAZARDOUS, SyncRegister, "Register as an idle script engine. Sync'ing with Scene won't start until \"sync start\". "); + + //For debugging load balancing and migration process + Command cmdSyncStartLB = new Command("startLB", CommandIntentions.COMMAND_HAZARDOUS, SyncStartLB, "Register as an idle script engine. Sync'ing with Scene won't start until \"sync start\". "); + + m_commander.RegisterCommand("start", cmdSyncStart); + m_commander.RegisterCommand("stop", cmdSyncStop); + m_commander.RegisterCommand("status", cmdSyncStatus); + m_commander.RegisterCommand("quarkSpace", cmdSyncSetQuarks); + m_commander.RegisterCommand("register", cmdSyncRegister); + m_commander.RegisterCommand("startLB", cmdSyncStartLB); + + lock (m_scene) + { + // Add this to our scene so scripts can call these functions + m_scene.RegisterModuleCommander(m_commander); + } + } + + + /// + /// Processes commandline input. Do not call directly. + /// + /// Commandline arguments + private void EventManager_OnPluginConsole(string[] args) + { + if (args[0] == "sync") + { + if (args.Length == 1) + { + m_commander.ProcessConsoleCommand("help", new string[0]); + return; + } + + string[] tmpArgs = new string[args.Length - 2]; + int i; + for (i = 2; i < args.Length; i++) + tmpArgs[i - 2] = args[i]; + + m_commander.ProcessConsoleCommand(args[1], tmpArgs); + } + } + + private void SyncStart(Object[] args) + { + lock (m_client_lock) + { + //if (m_scriptEngineToSceneConnector != null) + if(m_PEToSceneConnectors.Count>0) + { + string authScenes = ""; + foreach (KeyValuePair valPair in m_PEToSceneConnectors) + { + authScenes += valPair.Key + ", "; + } + m_log.WarnFormat(LogHeader+": Already synchronized to "+authScenes); + return; + } + //m_log.Warn("[REGION SYNC CLIENT MODULE] Starting synchronization"); + m_log.Warn(LogHeader + ": Starting RegionSyncPhysEngine"); + + if (m_sceneNum > 1) + { + //If there is no arguments following "sync start", then be default we will connect to one or more scenes. + //we need to create a connector to each authoritative scene + foreach (KeyValuePair valPair in m_authScenesInfoByName) + { + string authSceneName = valPair.Key; + AuthSceneInfo authSceneInfo = valPair.Value; + + //create a new connector, the local end of each connector, however, is linked to the ValidScene only, + //since all objects will be contained in this scene only + PhysEngineToSceneConnector scriptEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, m_debugWithViewer, authSceneName, m_syncConfig); + if (scriptEngineToSceneConnector.Start()) + { + m_PEToSceneConnectors.Add(authSceneName, scriptEngineToSceneConnector); + } + } + } + else + { + //Only one remote scene to connect to. Subscribe to whatever specified in the config file. + //List quarkStringList = RegionSyncUtil.QuarkStringToStringList(m_quarkListString); + //InitPhysEngineToSceneConnector(quarkStringList); + InitPhysEngineToSceneConnector(m_subscriptionSpaceString); + } + } + } + + private void SyncRegister(Object[] args) + { + //This should not happen. No-validLocalScene should not have register handlers for the command + //if (m_scene.RegionInfo.RegionName != m_validLocalScene) + // return; + + //Registration only, no state sync'ing yet. So only start the connector for the validLocalScene. (For now, we only test this with one scene, and + //quarks are smaller than a 256x256 scene. + string authSceneName = m_localToAuthSceneMapping[m_validLocalScene]; + AuthSceneInfo authSceneInfo = m_authScenesInfoByName[authSceneName]; + m_idlePEToSceneConnector = new PhysEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, m_debugWithViewer, authSceneName, m_syncConfig); + m_idlePEToSceneConnector.RegisterIdle(); + } + + /// + /// The given PhysEngineToSceneConnector, after having connected to the Scene (called its Start()), will + /// call this function to remove it self as an idle connector, and to be recorded as one working connector. + /// + /// + public void RecordSyncStartAfterLoadMigration(PhysEngineToSceneConnector seToSceneConnector) + { + foreach (KeyValuePair valPair in m_authScenesInfoByName) + { + string authSceneName = valPair.Key; + AuthSceneInfo authSceneInfo = valPair.Value; + + string localScene = m_authToLocalSceneMapping[authSceneName]; + + if (localScene != m_scene.RegionInfo.RegionName) + continue; + + if (m_PEToSceneConnectors.ContainsKey(authSceneName)) + { + m_log.Warn(LogHeader + ": Connector to " + authSceneName + " is already considered connected"); + return; + } + + m_PEToSceneConnectors.Add(authSceneName, seToSceneConnector); + //there should only be one element in the dictionary if we reach this loop, anyway, we break from it. + break; + } + m_idlePEToSceneConnector = null; + } + + private void SyncStartLB(Object[] args) + { + string authSceneName = m_localToAuthSceneMapping[m_validLocalScene]; + PhysEngineToSceneConnector sceneConnector = m_PEToSceneConnectors[authSceneName]; + // TODO: load balancing. Next line commented out + // sceneConnector.SendLoadBalanceRequest(); + } + + private void SetQuarkList(Object[] args) + { + m_subscriptionSpaceString = (string)args[0]; + + InitPhysEngineToSceneConnector(m_subscriptionSpaceString); + } + + private void SetQuarkSize(Object[] args) + { + QuarkInfo.SizeX = (int)args[0]; + QuarkInfo.SizeY = (int)args[1]; + + } + + private void InitPhysEngineToSceneConnector(string space) + { + + foreach (KeyValuePair valPair in m_authScenesInfoByName) + { + string authSceneName = valPair.Key; + AuthSceneInfo authSceneInfo = valPair.Value; + + string localScene = m_authToLocalSceneMapping[authSceneName]; + + if (localScene != m_scene.RegionInfo.RegionName) + continue; + + //create a new connector, the local end of each connector, however, is set of the ValidScene only, + //since all objects will be contained in this scene only + PhysEngineToSceneConnector scriptEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, + m_debugWithViewer, authSceneName, space, m_syncConfig); + if (scriptEngineToSceneConnector.Start()) + { + m_PEToSceneConnectors.Add(authSceneName, scriptEngineToSceneConnector); + } + + break; //there should only be one element in the dictionary if we reach this loop, anyway, we break from it. + } + } + + private void SyncStop(Object[] args) + { + lock (m_client_lock) + { + //if (m_scriptEngineToSceneConnector == null) + if(m_PEToSceneConnectors.Count==0 && m_idlePEToSceneConnector==null) + { + m_log.WarnFormat("[REGION SYNC PHYSICS ENGINE MODULE] Already stopped"); + return; + } + + if (m_PEToSceneConnectors.Count > 0) + { + foreach (KeyValuePair valPair in m_PEToSceneConnectors) + { + PhysEngineToSceneConnector connector = valPair.Value; + if (connector == null) + { + continue; + } + connector.Stop(); + } + m_PEToSceneConnectors.Clear(); + } + else if (m_idlePEToSceneConnector != null) + { + m_idlePEToSceneConnector.Stop(); + m_idlePEToSceneConnector = null; + } + + //m_scriptEngineToSceneConnector.Stop(); + //m_scriptEngineToSceneConnector = null; + m_log.Warn(LogHeader+": Stopping synchronization"); + } + + m_authScenesInfoByLoc.Clear(); + + //save script state and stop script instances + // TODO: Load balancing. next line commented out to compile + // m_scene.EventManager.TriggerPhysEngineSyncStop(); + //remove all objects + m_scene.DeleteAllSceneObjects(); + + } + + private void SyncStatus(Object[] args) + { + lock (m_client_lock) + { + if (m_PEToSceneConnectors.Count == 0) + { + m_log.WarnFormat("[REGION SYNC PHYSICS ENGINE MODULE] Not currently synchronized"); + return; + } + m_log.WarnFormat("[REGION SYNC PHYSICS ENGINE MODULE] Synchronized"); + foreach (KeyValuePair pair in m_PEToSceneConnectors) + { + PhysEngineToSceneConnector sceneConnector = pair.Value; + sceneConnector.ReportStatus(); + } + } + } + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs index 17f985a483..f2da4d636d 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs @@ -10,7 +10,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { Null, ClientManager, - ScriptEngine + ScriptEngine, + PhysicsEngine } #endregion diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs new file mode 100644 index 0000000000..86054428a4 --- /dev/null +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -0,0 +1,393 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Collections.Generic; +using System.Threading; +using OpenMetaverse; +using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Region.Framework.Interfaces; +using log4net; + +namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule +{ + + + + //KittyL: NOTE -- We need to define an interface for all actors to connect into the Scene, + // e.g. IActorConnector, that runs on the Scene side, processes messages from actors, + // and apply Scene/Object operations. + + // The SceneToPhysEngineConnector acts as a thread on the RegionSyncServer to handle incoming + // messages from PhysEngineToSceneConnectors that run on Physics Engines. It connects the + // authoratative Scene with remote script engines. + public class SceneToPhysEngineConnector + { + #region SceneToPhysEngineConnector members + + object stats = new object(); + private DateTime lastStatTime; + private long msgsIn; + private long msgsOut; + private long bytesIn; + private long bytesOut; + private long pollBlocks; + private int lastTotalCount; + private int lastLocalCount; + private int lastRemoteCount; + + private int msgCount = 0; + + // The TcpClient this view uses to communicate with its RegionSyncClient + private TcpClient m_tcpclient; + // Set the addr and port for TcpListener + private IPAddress m_addr; + private Int32 m_port; + private int m_connection_number; + private Scene m_scene; + + object m_syncRoot = new object(); + Dictionary m_syncedAvatars = new Dictionary(); + + // A queue for incoming and outgoing traffic + private OpenMetaverse.BlockingQueue inbox = new OpenMetaverse.BlockingQueue(); + private OpenMetaverse.BlockingQueue outbox = new OpenMetaverse.BlockingQueue(); + + private ILog m_log; + + private Thread m_receive_loop; + private string m_regionName; + + private SceneToPhysEngineSyncServer m_syncServer = null; + + // A string of the format [REGION SYNC SCRIPT API (regionname)] for use in log headers + private string LogHeader + { + get + { + if (m_regionName == null) + return String.Format("[SceneToPhysEngineConnector #{0}]", m_connection_number); + return String.Format("[SceneToPhysEngineConnector #{0} ({1:10})]", m_connection_number, m_regionName); + } + } + + // A string of the format "RegionSyncClientView #X" for use in describing the object itself + public string Description + { + get + { + if (m_regionName == null) + return String.Format("RegionSyncPhysAPI #{0}", m_connection_number); + return String.Format("RegionSyncPhysAPI #{0} ({1:10})", m_connection_number, m_regionName); + } + } + + public int ConnectionNum + { + get { return m_connection_number; } + } + + public string GetStats() + { + int syncedAvCount; + string ret; + //lock (m_syncRoot) + // syncedAvCount = m_syncedAvatars.Count; + lock (stats) + { + double secondsSinceLastStats = DateTime.Now.Subtract(lastStatTime).TotalSeconds; + lastStatTime = DateTime.Now; + + ret = String.Format("[{0,4}/{1,4}], [{2,4}/{3,4}], [{4,4}/{5,4}], [{6,4} ({7,4})], [{8,8} ({9,8:00.00})], [{10,4} ({11,4})], [{12,8} ({13,8:00.00})], [{14,8} ({15,4}]", + //lastTotalCount, totalAvCount, // TOTAL AVATARS + //lastLocalCount, syncedAvCount, // LOCAL TO THIS CLIENT VIEW + //lastRemoteCount, totalAvCount - syncedAvCount, // REMOTE (SHOULD = TOTAL - LOCAL) + msgsIn, (int)(msgsIn / secondsSinceLastStats), + bytesIn, 8 * (bytesIn / secondsSinceLastStats / 1000000), // IN + msgsOut, (int)(msgsOut / secondsSinceLastStats), + bytesOut, 8 * (bytesOut / secondsSinceLastStats / 1000000), // OUT + pollBlocks, (int)(pollBlocks / secondsSinceLastStats)); // NUMBER OF TIMES WE BLOCKED WRITING TO SOCKET + + msgsIn = msgsOut = bytesIn = bytesOut = pollBlocks = 0; + } + return ret; + } + + // Check if the client is connected + public bool Connected + { get { return m_tcpclient.Connected; } } + + //private int QuarkInfo.SizeX; + //private int QuarkInfo.SizeY; + //private List m_quarkSubscriptions; + Dictionary m_quarkSubscriptions; + public Dictionary QuarkSubscriptionList + { + get { return m_quarkSubscriptions; } + } + + + + #endregion + + // Constructor + public SceneToPhysEngineConnector(int num, Scene scene, TcpClient client, SceneToPhysEngineSyncServer syncServer) + { + m_connection_number = num; + m_scene = scene; + m_tcpclient = client; + m_addr = ((IPEndPoint)client.Client.RemoteEndPoint).Address; + m_port = ((IPEndPoint)client.Client.RemoteEndPoint).Port; + m_syncServer = syncServer; + + //QuarkInfo.SizeX = quarkSizeX; + //QuarkInfo.SizeY = quarkSizeY; + + m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + //m_log.WarnFormat("{0} Constructed", LogHeader); + + //Register for events from Scene.EventManager + //m_scene.EventManager.OnRezScript += SEConnectorOnRezScript; + //m_scene.EventManager.OnScriptReset += SEConnectorOnScriptReset; + //m_scene.EventManager.OnUpdateScript += SEConnectorOnUpdateScript; + // Create a thread for the receive loop + m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); })); + m_receive_loop.Name = Description; + //m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name); + m_receive_loop.Start(); + + //tell the remote script engine about the locX, locY of this authoritative scene + SendSceneLoc(); + } + + // Stop the listening thread, disconnecting the RegionSyncPhysEngine + public void Shutdown() + { + m_syncServer.RemoveSyncedPhysEngine(this); + // m_scene.EventManager.OnChatFromClient -= EventManager_OnChatFromClient; + // Abort ReceiveLoop Thread, close Socket and TcpClient + m_receive_loop.Abort(); + m_tcpclient.Client.Close(); + m_tcpclient.Close(); + + //m_scene.EventManager.OnRezScript -= SEConnectorOnRezScript; + //m_scene.EventManager.OnScriptReset -= SEConnectorOnScriptReset; + //m_scene.EventManager.OnUpdateScript -= SEConnectorOnUpdateScript; + } + + #region Send/Receive messages to/from the remote Physics Engine + + // Listen for messages from a RegionSyncClient + // *** This is the main thread loop for each connected client + private void ReceiveLoop() + { + //m_scene.EventManager.OnChatFromClient += new EventManager.ChatFromClientEvent(EventManager_OnChatFromClient); + + // Reset stats and time + lastStatTime = DateTime.Now; + msgsIn = msgsOut = bytesIn = bytesOut = 0; + + try + { + while (true) + { + RegionSyncMessage msg = GetMessage(); + lock (stats) + { + msgsIn++; + bytesIn += msg.Length; + } + lock (m_syncRoot) + HandleMessage(msg); + } + } + catch (Exception e) + { + m_log.WarnFormat("{0}: has disconnected: {1}", LogHeader, e.Message); + } + Shutdown(); + } + + // Get a message from the RegionSyncClient + private RegionSyncMessage GetMessage() + { + // Get a RegionSyncMessager from the incoming stream + RegionSyncMessage msg = new RegionSyncMessage(m_tcpclient.GetStream()); + //m_log.WarnFormat("{0} Received {1}", LogHeader, msg.ToString()); + return msg; + } + + // Handle an incoming message + // *** Perhaps this should not be synchronous with the receive + // We could handle messages from an incoming Queue + private void HandleMessage(RegionSyncMessage msg) + { + msgCount++; + //string handlerMessage = ""; + switch (msg.Type) + { + case RegionSyncMessage.MsgType.ActorStop: + { + Shutdown(); + } + return; + case RegionSyncMessage.MsgType.LoadBalanceRequest: + { + m_syncServer.HandleLoadBalanceRequest(this); + return; + } + + case RegionSyncMessage.MsgType.ActorStatus: + { + string status = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + ActorStatus actorStatus = (ActorStatus)Convert.ToInt32(status); + if (actorStatus == ActorStatus.Sync) + { + m_log.Debug(LogHeader + ": received ActorStatus " + actorStatus.ToString()); + m_syncServer.AddSyncedPhysEngine(this); + } + else + { + m_log.Warn(LogHeader + ": not supposed to received RegionSyncMessage.MsgType.ActorStatus==" + status.ToString()); + } + return; + } + + default: + { + m_log.WarnFormat("{0} Unable to handle unsupported message type", LogHeader); + return; + } + } + } + + //For simplicity, we assume the subscription sent by PhysEngine is legistimate (no overlapping with other script engines, etc) + private void HandleQuarkSubscription(RegionSyncMessage msg) + { + string quarkString = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + m_log.Debug(LogHeader + ": received quark-string: " + quarkString); + + List quarkStringList = RegionSyncUtil.QuarkStringToStringList(quarkString); + //m_quarkSubscriptions = RegionSyncUtil.GetQuarkInfoList(quarkStringList, QuarkInfo.SizeX, QuarkInfo.SizeY); + List quarkList = RegionSyncUtil.GetQuarkInfoList(quarkStringList); + m_syncServer.RegisterQuarkSubscription(quarkList, this); + + m_quarkSubscriptions = new Dictionary(); + foreach (QuarkInfo quark in quarkList) + { + m_quarkSubscriptions.Add(quark.QuarkStringRepresentation, quark); + } + } + + private RegionSyncMessage PrepareObjectUpdateMessage(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) + { + OSDMap data = new OSDMap(3); + data["locX"] = OSD.FromUInteger(m_scene.RegionInfo.RegionLocX); + data["locY"] = OSD.FromUInteger(m_scene.RegionInfo.RegionLocY); + string sogxml = SceneObjectSerializer.ToXml2Format(sog); + data["sogXml"] = OSD.FromString(sogxml); + + RegionSyncMessage rsm = new RegionSyncMessage(msgType, OSDParser.SerializeJsonString(data)); + return rsm; + } + + private void SendSceneLoc() + { + uint locX = m_scene.RegionInfo.RegionLocX; + uint locY = m_scene.RegionInfo.RegionLocY; + + OSDMap data = new OSDMap(2); + data["locX"] = OSD.FromUInteger(locX); + data["locY"] = OSD.FromUInteger(locY); + Send(new RegionSyncMessage(RegionSyncMessage.MsgType.SceneLocation, OSDParser.SerializeJsonString(data))); + } + + public void Send(RegionSyncMessage msg) + { + if (msg.Type == RegionSyncMessage.MsgType.AvatarAppearance) + m_log.WarnFormat("{0} Sending AvatarAppearance to client manager", LogHeader); + + Send(msg.ToBytes()); + } + + private void Send(byte[] data) + { + if (m_tcpclient.Connected) + { + try + { + lock (stats) + { + msgsOut++; + bytesOut += data.Length; + } + m_tcpclient.GetStream().BeginWrite(data, 0, data.Length, ar => + { + if (m_tcpclient.Connected) + { + try + { + m_tcpclient.GetStream().EndWrite(ar); + } + catch (Exception) + { } + } + }, null); + } + catch (IOException) + { + m_log.WarnFormat("{0} Physics Engine has disconnected.", LogHeader); + } + } + } + + public void SendObjectUpdate(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) + { + Send(PrepareObjectUpdateMessage(msgType, sog)); + } + + #endregion Send/Receive messages to/from the remote Physics Engine + + #region Spacial query functions (should be eventually implemented within Scene) + + //This should be a function of Scene, but since we don't have the quark concept in Scene yet, + //for now we implement it here. + //Ideally, for quark based space representation, the Scene has a list of quarks, and each quark points + //to a list of objects within that quark. Then it's much easier to return the right set of objects within + //a certain space. (Or use DB that supports spatial queries.) + List GetObjectsInGivenSpace(Scene scene, Dictionary quarkSubscriptions) + { + List entities = m_scene.GetEntities(); + List sogList = new List(); + foreach (EntityBase e in entities) + { + if (e is SceneObjectGroup) + { + SceneObjectGroup sog = (SceneObjectGroup)e; + string quarkID = RegionSyncUtil.GetQuarkIDByPosition(sog.AbsolutePosition); + if (m_quarkSubscriptions.ContainsKey(quarkID)) + { + sogList.Add(sog); + } + } + } + + return sogList; + } + + #endregion + + #region Load balancing functions + public void SendLoadBalanceRejection(string response) + { + RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.LoadBalanceRejection, response); + Send(msg); + } + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs new file mode 100644 index 0000000000..44f64e5bef --- /dev/null +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -0,0 +1,480 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Collections.Generic; +using System.Threading; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using log4net; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Region.Framework.Scenes.Serialization; + +namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule +{ + //Information of a registered idle physics engine. + //Note, this is a temporary solution to inlcude idle physics engines here. + //In the future, there might be a independent load balaner that keeps track + //of available idle hardware. + public class IdlePhysEngineInfo + { + public TcpClient TClient; + //public IPAddress PhysEngineIPAddr; + //public int PhysEnginePort; + public string ID; + + //Will be used to store the overloaded PE that has send LB request and paired with this idle PE + public SceneToPhysEngineConnector AwaitOverloadedSE=null; + + public IdlePhysEngineInfo(TcpClient tclient) + { + if(tclient==null) return; + TClient = tclient; + IPAddress ipAddr = ((IPEndPoint)tclient.Client.RemoteEndPoint).Address; + int port = ((IPEndPoint)tclient.Client.RemoteEndPoint).Port; + ID = ipAddr.ToString()+":"+port; + } + } + + //Here is the per actor type listening server for physics Engines. + public class SceneToPhysEngineSyncServer + { + #region SceneToPhysEngineSyncServer members + // Set the addr and port for TcpListener + private IPAddress m_addr; + private Int32 m_port; + + //this field is only meaning for the QuarkInfo records on the Scene side + private SceneToPhysEngineConnector m_peConnector=null; + public SceneToPhysEngineConnector PEConnector + { + get { return m_peConnector; } + set { m_peConnector = value; } + } + + private int peCounter; + + // The local scene. + private Scene m_scene; + + private ILog m_log; + + // The listener and the thread which listens for connections from client managers + private TcpListener m_listener; + private Thread m_listenerThread; + + private object m_physEngineConnector_lock = new object(); + //private Dictionary m_physEngineConnectors = new Dictionary(); + private List m_physEngineConnectors = new List(); + + //list of idle physics engines that have registered. + private List m_idlePhysEngineList = new List(); + + //List of all quarks, each using the concatenation of x,y values of its left-bottom corners, + // where the x,y values are the offset position in the scene. + private Dictionary m_quarksInScene = new Dictionary(); + + private string LogHeader = "[SCENE TO PHYS ENGINE SYNC SERVER]"; + + //Quark related info + //private int QuarkInfo.SizeX; + //private int QuarkInfo.SizeY; + + // Check if any of the client views are in a connected state + public bool Synced + { + get + { + return (m_physEngineConnectors.Count > 0); + } + } + #endregion + + // Constructor + public SceneToPhysEngineSyncServer(Scene scene, string addr, int port) + { + if (QuarkInfo.SizeX == -1 || QuarkInfo.SizeY == -1) + { + m_log.Error(LogHeader + " QuarkInfo.SizeX or QuarkInfo.SizeY has not been configured yet."); + Environment.Exit(0); ; + } + + m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + //m_log.Warn(LogHeader + "Constructed"); + m_scene = scene; + m_addr = IPAddress.Parse(addr); + m_port = port; + + InitQuarksInScene(); + SubscribeToEvents(); + } + + + private void SubscribeToEvents() + { + } + + private void UnSubscribeToEvents() + { + } + + // Start the server + public void Start() + { + m_listenerThread = new Thread(new ThreadStart(Listen)); + m_listenerThread.Name = "SceneToPhysEngineSyncServer Listener"; + m_log.WarnFormat(LogHeader + ": Starting {0} thread", m_listenerThread.Name); + m_listenerThread.Start(); + //m_log.Warn("[REGION SYNC SERVER] Started"); + } + + + + // Stop the server and disconnect all RegionSyncClients + public void Shutdown() + { + // Stop the listener and listening thread so no new clients are accepted + m_listener.Stop(); + m_listenerThread.Abort(); + m_listenerThread = null; + + // Stop all existing SceneTOSEConnectors + //TO FINISH + foreach (SceneToPhysEngineConnector peConnector in m_physEngineConnectors) + { + peConnector.Shutdown(); + } + m_physEngineConnectors.Clear(); + + UnSubscribeToEvents(); + } + + private void InitQuarksInScene() + { + List quarkList = RegionSyncUtil.GetAllQuarksInScene(); + foreach (QuarkInfo quark in quarkList) + { + m_quarksInScene.Add(quark.QuarkStringRepresentation, quark); + } + } + + public void RegisterQuarkSubscription(List quarkSubscriptions, SceneToPhysEngineConnector peConnector) + { + foreach (QuarkInfo quark in quarkSubscriptions) + { + string quarkID = quark.QuarkStringRepresentation; + // TODO: does the physics engine connect to quarks. Next line commented out. + // m_quarksInScene[quarkID].PEConnector = peConnector; + m_log.Debug(LogHeader + ": " + quarkID + " subscribed by "+peConnector.Description); + } + } + + // Add a connector to a physics engine + public void AddSyncedPhysEngine(SceneToPhysEngineConnector peConnector) + { + lock (m_physEngineConnector_lock) + { + //Dictionary currentlist = m_physEngineConnectors; + //Dictionary newlist = new Dictionary(currentlist); + m_physEngineConnectors.Add(peConnector); + // Threads holding the previous version of the list can keep using it since + // they will not hold it for long and get a new copy next time they need to iterate + //m_physEngineConnectors = newlist; + } + } + + // Remove the client view from the list and decrement synced client counter + public void RemoveSyncedPhysEngine(SceneToPhysEngineConnector peConnector) + { + lock (m_physEngineConnector_lock) + { + //Dictionary currentlist = m_physEngineConnectors; + //Dictionary newlist = new Dictionary(currentlist); + m_physEngineConnectors.Remove(peConnector); + // Threads holding the previous version of the list can keep using it since + // they will not hold it for long and get a new copy next time they need to iterate + //m_physEngineConnectors = newlist; + } + } + + // Listen for connections from a new RegionSyncClient + // When connected, start the ReceiveLoop for the new client + private void Listen() + { + m_listener = new TcpListener(m_addr, m_port); + + try + { + // Start listening for clients + m_listener.Start(); + while (true) + { + // *** Move/Add TRY/CATCH to here, but we don't want to spin loop on the same error + m_log.WarnFormat(LogHeader + ": Listening for new connections on port {0}...", m_port.ToString()); + TcpClient tcpclient = m_listener.AcceptTcpClient(); + IPAddress addr = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Address; + int port = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Port; + + ActorStatus actorStatus = GetActorStatus(tcpclient); + + switch (actorStatus) + { + case ActorStatus.Sync: + // Add the SceneToPhysEngineConnector to the list + SceneToPhysEngineConnector sceneToPEConnector = new SceneToPhysEngineConnector(++peCounter, m_scene, tcpclient, this); + AddSyncedPhysEngine(sceneToPEConnector); + break; + case ActorStatus.Idle: + IdlePhysEngineInfo idleSE = new IdlePhysEngineInfo(tcpclient); + m_log.Debug(": adding an idle SE ("+addr+","+port+")"); + m_idlePhysEngineList.Add(idleSE); + break; + default: + break; + } + + } + } + catch (SocketException e) + { + m_log.WarnFormat(LogHeader + " [Listen] SocketException: {0}", e); + } + } + + /* + public void RegisterSyncedPhysEngine(SceneToPhysEngineConnector sceneToSEConnector) + { + //first, remove it from the idle list + m_idlePhysEngineList.Remove(sceneToSEConnector); + + //now, added to the synced SE list + AddSyncedPhysEngine(sceneToSEConnector); + } + * */ + + + // Broadcast a message to all connected RegionSyncClients + public void SendToAllConnectedPE(RegionSyncMessage msg) + { + if (m_physEngineConnectors.Count > 0) + { + m_log.Debug(LogHeader + ": region " + m_scene.RegionInfo.RegionName + " Broadcast to PhysEngine, msg " + msg.Type); + foreach (SceneToPhysEngineConnector peConnector in m_physEngineConnectors) + { + peConnector.Send(msg); + } + } + + } + + //TO FINISH: Find the right SceneToSEConnector to forward the message + public void SendToPE(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) + { + SceneToPhysEngineConnector peConnector = GetSceneToPEConnector(sog); + if (peConnector != null) + { + peConnector.SendObjectUpdate(msgType, sog); + } + } + + //This is to send a message, rsm, to phys engine, and the message is about object SOG. E.g. RemovedObject + public void SendToPE(RegionSyncMessage rsm, SceneObjectGroup sog) + { + SceneToPhysEngineConnector peConnector = GetSceneToPEConnector(sog); + if (peConnector != null) + { + peConnector.Send(rsm); + } + } + + + private SceneToPhysEngineConnector GetSceneToPEConnector(SceneObjectGroup sog) + { + if (m_physEngineConnectors.Count == 0) + return null; + if (sog == null) + { + return m_physEngineConnectors[0]; + } + else + { + //Find the right SceneToSEConnector by the object's position + //TO FINISH: Map the object to a quark first, then map the quark to SceneToSEConnector + string quarkID = RegionSyncUtil.GetQuarkIDByPosition(sog.AbsolutePosition); + // TODO: connection of physics engine to quarks. Next line commented out + // SceneToPhysEngineConnector peConnector = m_quarksInScene[quarkID].PEConnector; + + if (PEConnector == null) + { + m_log.Warn(LogHeader + sog.AbsolutePosition.ToString() + " not covered by any physics engine"); + } + + return PEConnector; + } + + } + + private ActorStatus GetActorStatus(TcpClient tcpclient) + { + m_log.Debug(LogHeader+ ": Get Actor status"); + + RegionSyncMessage msg = new RegionSyncMessage(tcpclient.GetStream()); + ActorStatus actorStatus; + switch (msg.Type) + { + case RegionSyncMessage.MsgType.ActorStatus: + { + string status = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + m_log.Debug(LogHeader + ": recv status: " + status); + actorStatus = (ActorStatus)Convert.ToInt32(status); + break; + } + default: + { + m_log.Error(LogHeader + ": Expect Message Type: ActorStatus"); + RegionSyncMessage.HandleError("[REGION SYNC SERVER]", msg, String.Format("{0} Expect Message Type: ActorType", "[REGION SYNC SERVER]")); + return ActorStatus.Null; + } + } + return actorStatus; + } + + + #region Event Handlers + + #endregion Event Handlers + + #region Load balancing members and functions + //keep track of idle physics engines that are in the process of load balancing (they are off the idle list, but not a working physics engine yet (not sync'ing with Scene yet)). + private Dictionary m_loadBalancingIdleSEs = new Dictionary(); + public void HandleLoadBalanceRequest(SceneToPhysEngineConnector seConnctor) + { + //Let's start a thread to do the job, so that we can return quickly and don't block on ReceiveLoop() + + Thread partitionThread = new Thread(new ParameterizedThreadStart(TriggerLoadBalanceProcess)); + partitionThread.Name = "TriggerLoadBalanceProcess"; + partitionThread.Start((object)seConnctor); + } + + public void TriggerLoadBalanceProcess(object arg) + { + SceneToPhysEngineConnector seConnctor = (SceneToPhysEngineConnector)arg; + IdlePhysEngineInfo idlePhysEngineInfo = GetIdlePhysEngineConnector(); + if (idlePhysEngineInfo != null) + { + RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.LoadMigrationNotice); + Send(idlePhysEngineInfo.TClient, msg.ToBytes()); + m_log.Debug(LogHeader + ": HandleLoadBalanceRequest from " + seConnctor.Description + ", picked idle SE: " + idlePhysEngineInfo.ID); + + //keep track of which overload physics engine is paired up with which idle physics engine + idlePhysEngineInfo.AwaitOverloadedSE = seConnctor; + m_loadBalancingIdleSEs.Add(idlePhysEngineInfo.ID, idlePhysEngineInfo); + + m_log.Debug("ToSEConnector portal: local -" + + ((IPEndPoint)idlePhysEngineInfo.TClient.Client.LocalEndPoint).Address.ToString() + ":" + ((IPEndPoint)idlePhysEngineInfo.TClient.Client.LocalEndPoint).Port + + "; remote - " + ((IPEndPoint)idlePhysEngineInfo.TClient.Client.RemoteEndPoint).Address.ToString() + ":" + + ((IPEndPoint)idlePhysEngineInfo.TClient.Client.RemoteEndPoint).Port); + + //Now we expect the idle physics engine to reply back + msg = new RegionSyncMessage(idlePhysEngineInfo.TClient.GetStream()); + if (msg.Type != RegionSyncMessage.MsgType.LoadMigrationListenerInitiated) + { + m_log.Warn(LogHeader + ": should receive a message of type LoadMigrationListenerInitiated, but received " + msg.Type.ToString()); + } + else + { + //Before the load is migrated from overloaded physics engine to the idle engine, sync with the DB to update the state in DB + List entities = m_scene.GetEntities(); + foreach (EntityBase entity in entities) + { + if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged) + { + m_scene.ForceSceneObjectBackup((SceneObjectGroup)entity); + } + } + + OSDMap data = DeserializeMessage(msg); + if (!data.ContainsKey("ip") || !data.ContainsKey("port") ) + { + m_log.Warn(LogHeader + ": parameters missing in SceneLocation message from Scene, need to have ip, port"); + return; + } + //echo the information back to the overloaded physics engine + seConnctor.Send(new RegionSyncMessage(RegionSyncMessage.MsgType.LoadBalanceResponse, OSDParser.SerializeJsonString(data))); + + m_log.Debug(LogHeader + " now remove physics engine " + idlePhysEngineInfo.ID + " from idle SE list, and create SceneToPhysEngineConnector to it"); + //create a SceneToSEConnector for the idle physics engine, who will be sync'ing with this SyncServer soon + SceneToPhysEngineConnector sceneToSEConnector = new SceneToPhysEngineConnector(++peCounter, m_scene, idlePhysEngineInfo.TClient, this); + //Now remove the physics engine from the idle SE list + m_idlePhysEngineList.Remove(idlePhysEngineInfo); + //AddSyncedPhysEngine(sceneToSEConnector); + } + + } + else + { + seConnctor.SendLoadBalanceRejection("no idle physics engines"); + } + } + + HashSet exceptions = new HashSet(); + private OSDMap DeserializeMessage(RegionSyncMessage msg) + { + OSDMap data = null; + try + { + data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap; + } + catch (Exception e) + { + lock (exceptions) + // If this is a new message, then print the underlying data that caused it + if (!exceptions.Contains(e.Message)) + m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); + data = null; + } + return data; + } + + private void Send(TcpClient tcpclient, byte[] data) + { + if (tcpclient.Connected) + { + try + { + tcpclient.GetStream().BeginWrite(data, 0, data.Length, ar => + { + if (tcpclient.Connected) + { + try + { + tcpclient.GetStream().EndWrite(ar); + } + catch (Exception) + { } + } + }, null); + } + catch (IOException) + { + m_log.WarnFormat("{0} physics Engine has disconnected.", LogHeader); + } + } + } + + private IdlePhysEngineInfo GetIdlePhysEngineConnector() + { + if (m_idlePhysEngineList.Count == 0) + return null; + IdlePhysEngineInfo idleSEInfo = m_idlePhysEngineList[0]; + m_idlePhysEngineList.Remove(idleSEInfo); + return idleSEInfo; + } + + #endregion Load balancing functions + } +} diff --git a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs new file mode 100755 index 0000000000..45573e504b --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs @@ -0,0 +1,53 @@ +/* + * 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 OpenSim 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. + */ + +//KittyL: Added to support running script engine actor + +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.Interfaces +{ + //the interface for Scene to sync with Script Engine + public interface IPhysEngineToSceneConnectorModule + { + bool Active { get; } + bool Synced { get; } + bool DebugWithViewer { get; } + //void SendCoarseLocations(); + /// + /// Update the property of prim with primID, where the prim is located at quark (LocX, LocY). The length of each quark is configurable. + /// + /// + /// + /// + /// + /// + void SendSetPrimProperties(uint locX, uint locY, UUID primID, string pName, object pValue); + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f93832147c..9cd6db8160 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -378,8 +378,6 @@ namespace OpenSim.Region.Framework.Scenes protected IScriptEngineToSceneConnectorModule m_scriptEngineToSceneConnectorModule; - - public IScriptEngineToSceneConnectorModule ScriptEngineToSceneConnectorModule { get { return m_scriptEngineToSceneConnectorModule; } @@ -404,6 +402,48 @@ namespace OpenSim.Region.Framework.Scenes return IsSyncedServer(); } + /////////////////////////////////////////////////////////////////////////////////////////////// + //RA: Physics Engine + /////////////////////////////////////////////////////////////////////////////////////////////// + protected IPhysEngineToSceneConnectorModule m_physEngineToSceneConnectorModule = null; + public IPhysEngineToSceneConnectorModule PhysEngineToSceneConnectorModule + { + get { return m_physEngineToSceneConnectorModule; } + set { m_physEngineToSceneConnectorModule = value; } + } + + // list of physactors for this scene so we can find them later for remote physics + public Dictionary PhysActors = new Dictionary(); + public void AddPhysActor(uint id, PhysicsActor pActor) + { + if (PhysActors.ContainsKey(id)) { + PhysActors.Remove(id); + } + PhysActors.Add(id, pActor); + return; + } + public void RemovePhysActor(uint id) + { + if (PhysActors.ContainsKey(id)) { + PhysActors.Remove(id); + } + return; + } + + public bool IsPhysEngineScene() + { + return (SceneToPhysEngineConnectorModule != null); + } + public bool IsActivePhysEngineScene() + { + return (SceneToPhysEngineConnectorModule != null && SceneToPhysEngineConnectorModule.Active); + } + public bool IsPhysEngineActor() + { + return (PhysEngineToSceneConnectorModule != null); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// //This function should only be called by an actor who's local Scene is just a cache of the authorative Scene. //If the object already exists, use the new copy to replace it. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1476e98678..67fb6fe791 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -997,6 +997,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.PhysActor != null) { + Scene.RemovePhysActor(m_rootPart.PhysActor.LocalID); m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); m_rootPart.PhysActor = null; } @@ -1584,7 +1585,8 @@ namespace OpenSim.Region.Framework.Scenes dupe.RootPart.RotationOffset, dupe.RootPart.PhysActor.IsPhysical); - dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + // RA: Register physActor in scene dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); } @@ -2273,6 +2275,7 @@ namespace OpenSim.Region.Framework.Scenes //if (linkPart.PhysActor != null) //{ + // m_scene.RemovePhysActor(linkPart.PhysActor.LocalID); // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); //linkPart.PhysActor = null; @@ -2386,7 +2389,8 @@ namespace OpenSim.Region.Framework.Scenes linkPart.LinkNum = 0; if (linkPart.PhysActor != null) - { + { + m_scene.RemovePhysActor(linkPart.PhysActor.LocalID); m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a8de2da8e9..b797ef78d0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1491,7 +1491,9 @@ 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.LocalID = LocalId; + PhysActor.LocalID = LocalId; + // RA: register PhysActor with the scene + ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); DoPhysicsPropertyUpdate(RigidBody, true); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } @@ -1754,6 +1756,7 @@ namespace OpenSim.Region.Framework.Scenes // If we're not what we're supposed to be in the physics scene, recreate ourselves. + //ParentGroup.Scene.RemovePhysActor(PhysActor.LocalID); //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public //PhysActor = null; @@ -4283,6 +4286,7 @@ namespace OpenSim.Region.Framework.Scenes AddFlag(PrimFlags.Phantom); if (PhysActor != null) { + ParentGroup.Scene.RemovePhysActor(PhysActor.LocalID); m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public PhysActor = null; @@ -4307,7 +4311,9 @@ namespace OpenSim.Region.Framework.Scenes pa = PhysActor; if (pa != null) { - pa.LocalID = LocalId; + pa.LocalID = LocalId; + // RA: register PhysActor with scene + ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 880c3ea3cb..aa43e97be1 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -140,9 +140,10 @@ namespace OpenSim.Region.Physics.Manager public abstract Vector3 Size { get; set; } - public abstract PrimitiveBaseShape Shape { set; } - - public abstract uint LocalID { set; } + public abstract PrimitiveBaseShape Shape { set; } + + // RA: used to be abstract but changed to allow 'get' without changing all the phys engines + public virtual uint LocalID { set { return; } get { return 0; } } public abstract bool Grabbed { set; } @@ -157,8 +158,8 @@ namespace OpenSim.Region.Physics.Manager public abstract void delink(); - public abstract void LockAngularMotion(Vector3 axis); - + public abstract void LockAngularMotion(Vector3 axis); + public virtual void RequestPhysicsterseUpdate() { // Make a temporary copy of the event to avoid possibility of @@ -279,7 +280,8 @@ namespace OpenSim.Region.Physics.Manager public override uint LocalID { - set { return; } + set { return; } + get { return 0; } } public override bool Grabbed diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 7fd59a0ebf..234a677701 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -2766,6 +2766,7 @@ namespace OpenSim.Region.Physics.OdePlugin //Watchdog.UpdateThread(); } + #region Ninja Joints if (SupportsNINJAJoints) { // Create pending joints, if possible @@ -2947,6 +2948,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } } +#endregion Ninja Joints if (processedtaints) //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); diff --git a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs index 9cb43463ff..05ce620d0d 100755 --- a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs +++ b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs @@ -86,31 +86,32 @@ public class PECharacter : PhysicsActor public override Vector3 Size { get { return _size; } set { _size = value; - m_log.Debug("[PEE] PEChar set Size"); + m_log.Debug("[RPE] PEChar set Size"); Prop.Set(_localID, PropType.Size, _size); } } public override PrimitiveBaseShape Shape { set { _pbs = value; - m_log.Debug("[PEE] PEChar set Shape"); + m_log.Debug("[RPE] PEChar set Shape"); Prop.Set(_localID, PropType.Shape, _pbs); } } public override uint LocalID { set { _localID = value; - m_log.Debug("[PEE] PEChar set LocalID"); + m_log.Debug("[RPE] PEChar set LocalID"); Prop.Set(_localID, PropType.LocalID, _localID); - } + } + get { return _localID; } } public override bool Grabbed { set { _grabbed = value; - m_log.Debug("[PEE] PEChar set Grabbed"); + m_log.Debug("[RPE] PEChar set Grabbed"); Prop.Set(_localID, PropType.Grabbed, _grabbed); } } public override bool Selected { set { _selected = value; - m_log.Debug("[PEE] PEChar set Selected"); + m_log.Debug("[RPE] PEChar set Selected"); Prop.Set(_localID, PropType.Selected, _selected); } } @@ -122,7 +123,7 @@ public class PECharacter : PhysicsActor public override Vector3 Position { get { return _position; } set { _position = value; - // m_log.Debug("[PEE] PEChar set Position"); + // m_log.Debug("[RPE] PEChar set Position"); Prop.Set(_localID, PropType.Position, _position); } } @@ -132,7 +133,7 @@ public class PECharacter : PhysicsActor public override Vector3 Force { get { return _force; } set { _force = value; - m_log.Debug("[PEE] PEChar set Force"); + m_log.Debug("[RPE] PEChar set Force"); Prop.Set(_localID, PropType.Force, _force); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs b/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs index 1674b183f8..97b9267d96 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPlugin.cs @@ -57,7 +57,7 @@ public class PEPlugin : IPhysicsPlugin public string GetName() { - return ("PhysicsEngineEngine"); + return ("RemotePhysicsEngine"); } public void Dispose() diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 7d35d065b0..6a6c03eab2 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -84,31 +84,32 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Size { get { return _size; } set { _size = value; - m_log.Debug("[PEE] PEPrim set Size"); + m_log.Debug("[RPE] PEPrim set Size"); Prop.Set(_localID, PropType.Size, _size); } } public override PrimitiveBaseShape Shape { set { _pbs = value; - m_log.Debug("[PEE] PEPrim set Shape"); + m_log.Debug("[RPE] PEPrim set Shape"); Prop.Set(_localID, PropType.Shape, _pbs); } } public override uint LocalID { set { _localID = value; - m_log.Debug("[PEE] PEPrim set LocalID"); + m_log.Debug("[RPE] PEPrim set LocalID"); Prop.Set(_localID, PropType.LocalID, _localID); - } + } + get { return _localID; } } public override bool Grabbed { set { _grabbed = value; - m_log.Debug("[PEE] PEPrim set Grabbed"); + m_log.Debug("[RPE] PEPrim set Grabbed"); Prop.Set(_localID, PropType.Grabbed, _grabbed); } } public override bool Selected { set { _selected = value; - m_log.Debug("[PEE] PEPrim set Selected"); + m_log.Debug("[RPE] PEPrim set Selected"); Prop.Set(_localID, PropType.Selected, _selected); } } @@ -120,7 +121,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Position { get { return _position; } set { _position = value; - m_log.Debug("[PEE] PEPrim set Position"); + m_log.Debug("[RPE] PEPrim set Position"); Prop.Set(_localID, PropType.Position, _position); } } @@ -130,7 +131,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Force { get { return _force; } set { _force = value; - m_log.Debug("[PEE] PEPrim set Force"); + m_log.Debug("[RPE] PEPrim set Force"); Prop.Set(_localID, PropType.Force, _force); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PEScene.cs b/OpenSim/Region/Physics/PEPlugin/PEScene.cs index e47f06689e..8df6b2e24c 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEScene.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEScene.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using Nini.Config; +using log4net; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; using OpenMetaverse; @@ -34,6 +35,12 @@ namespace OpenSim.Region.Physics.PEPlugin { public class PEScene : PhysicsScene { + private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private List m_avatars = new List(); + private List m_prims = new List(); + private float[] m_heightMap; + public PEScene(string identifier) { } @@ -46,15 +53,32 @@ public class PEScene : PhysicsScene { PECharacter actor = new PECharacter(avName, this, position, null, size, 0f, 0f, .5f, 1f, 1f, 1f, .5f, .5f); + m_avatars.Add(actor); return actor; } public override void RemoveAvatar(PhysicsActor actor) { + try + { + m_avatars.Remove((PECharacter)actor); + } + catch (Exception e) + { + m_log.WarnFormat("[RPE]: Attempt to remove avatar that is not in physics scene: {0}", e); + } } public override void RemovePrim(PhysicsActor prim) { + try + { + m_prims.Remove((PEPrim)prim); + } + catch (Exception e) + { + m_log.WarnFormat("[RPE]: Attempt to remove prim that is not in physics scene: {0}", e); + } } public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, @@ -66,6 +90,7 @@ public class PEScene : PhysicsScene Vector3 size, Quaternion rotation, bool isPhysical) { PEPrim prim = new PEPrim(primName, this, position, size, rotation, null, pbs, isPhysical, null); + m_prims.Add(prim); return prim; } @@ -73,12 +98,62 @@ public class PEScene : PhysicsScene public override float Simulate(float timeStep) { + foreach (PECharacter actor in m_avatars) + { + Vector3 actorPosition = actor.Position; + Vector3 actorVelocity = actor.Velocity; + + actorPosition.X += actor.Velocity.X*timeStep; + actorPosition.Y += actor.Velocity.Y*timeStep; + + actorPosition.Y = Math.Max(actorPosition.Y, 0.1f); + actorPosition.Y = Math.Min(actorPosition.Y, Constants.RegionSize - 0.1f); + actorPosition.X = Math.Max(actorPosition.X, 0.1f); + actorPosition.X = Math.Min(actorPosition.X, Constants.RegionSize - 0.1f); + + float height = 25.0F; + try + { + height = m_heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + actor.Size.Z; + } + catch (OverflowException) + { + m_log.WarnFormat("[RPE]: Actor out of range: {0}", actor.SOPName, actor.Position.ToString()); + } + + if (actor.Flying) + { + if (actor.Position.Z + (actor.Velocity.Z*timeStep) < + m_heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2) + { + actorPosition.Z = height; + actorVelocity.Z = 0; + actor.IsColliding = true; + } + else + { + actorPosition.Z += actor.Velocity.Z*timeStep; + actor.IsColliding = false; + } + } + else + { + actorPosition.Z = height; + actorVelocity.Z = 0; + actor.IsColliding = true; + } + + actor.Position = actorPosition; + actor.Velocity = actorVelocity; + } return 60f; // returns frames per second } public override void GetResults() { } - public override void SetTerrain(float[] heightMap) { } + public override void SetTerrain(float[] heightMap) { + m_heightMap = heightMap; + } public override void SetWaterLevel(float baseheight) { } From 24bef963c790d50f28f1f15e3101c7c883e8c29a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 6 Dec 2010 10:57:39 -0800 Subject: [PATCH 03/15] Initial connection of phys actor --- .../PhysEngineToSceneConnector.cs | 105 +--- .../PhysEngineToSceneConnectorModule.cs | 550 +++--------------- .../RegionSyncServerModule.cs | 17 + .../SceneToPhysEngineSyncServer.cs | 21 +- .../IPhysEngineToSceneConnectorModule.cs | 15 +- OpenSim/Region/Framework/Scenes/Scene.cs | 58 +- .../Framework/Scenes/SceneObjectGroup.cs | 8 +- .../Framework/Scenes/SceneObjectPart.cs | 12 +- .../Region/Physics/Manager/PhysicsActor.cs | 12 +- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 5 +- prebuild.xml | 3 + 11 files changed, 171 insertions(+), 635 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 11f71c699e..4680dc50e0 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -63,7 +63,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // The client connection to the RegionSyncServer private TcpClient m_client = new TcpClient(); - private string m_authSceneName; //KittyL: Comment out m_statsTimer for now, will figure out whether we need it for PhysEngine later //private System.Timers.Timer m_statsTimer = new System.Timers.Timer(30000); @@ -94,7 +93,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Constructor - public PhysEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, string authSceneName, IConfig sysConfig) + public PhysEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, + IConfig sysConfig) { m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); m_validLocalScene = validLocalScene; @@ -102,7 +102,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_addrString = addr; m_port = port; m_debugWithViewer = debugWithViewer; - m_authSceneName = authSceneName; //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); m_sysConfig = sysConfig; @@ -110,53 +109,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_subscribedQuarks = new QuarkSubsriptionInfo(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); } - /// - /// Create a PhysEngineToSceneConnector based on the space it is supposed to subscribe (and operate) on. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public PhysEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, string authSceneName, - string subscriptionSpace, IConfig sysConfig) - { - if (QuarkInfo.SizeX == -1 || QuarkInfo.SizeY == -1) - { - m_log.Error("QuarkInfo.SizeX or QuarkInfo.SizeY has not been configured."); - Environment.Exit(0); - } - - m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - m_validLocalScene = validLocalScene; - m_addr = IPAddress.Parse(addr); - m_addrString = addr; - m_port = port; - m_debugWithViewer = debugWithViewer; - m_authSceneName = authSceneName; - //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); - m_sysConfig = sysConfig; - - m_subscribedQuarks = new QuarkSubsriptionInfo(subscriptionSpace); - } - - public PhysEngineToSceneConnectorModule GetPEToSceneConnectorMasterModule() - { - if (m_validLocalScene == null) - return null; - return (PhysEngineToSceneConnectorModule)m_validLocalScene.PhysEngineToSceneConnectorModule; - } - - public Scene GetValidLocalScene() - { - return m_validLocalScene; - } - - private List GetQuarkStringList() { List quarkList = new List(); @@ -167,19 +119,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return quarkList; } - - - /// - /// Get the reference to the local scene that is supposed to be mapped to the remote auth. scene. - /// - /// - /// - private Scene GetLocalScene(string authSceneName) - { - PhysEngineToSceneConnectorModule connectorModule = GetPEToSceneConnectorMasterModule(); - return connectorModule.GetLocalScene(authSceneName); - } - // Start the RegionSyncPhysEngine client thread public bool Start() { @@ -474,28 +413,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { case RegionSyncMessage.MsgType.RegionName: { - string authSceneName = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - if (authSceneName != m_authSceneName) - { - //This should not happen. If happens, check the configuration files (OpenSim.ini) on other sides. - m_log.Warn(": !!! Mismatch between configurations of authoritative scene. Script Engine's config: "+m_authSceneName+", Scene's config: "+authSceneName); - return; - } - RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_authSceneName)); return; } case RegionSyncMessage.MsgType.Terrain: { //We need to handle terrain differently as we handle objects: we really will set the HeightMap //of each local scene that is the shadow copy of its auth. scene. - Scene localScene = GetLocalScene(m_authSceneName); - if (localScene == null) - { - m_log.Warn("no local Scene mapped to "+m_authSceneName); - return; - } - localScene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); - RegionSyncMessage.HandleSuccess(LogHeader, msg, "Synchronized terrain"); return; } case RegionSyncMessage.MsgType.NewObject: @@ -556,24 +479,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule #endregion Utility functions - #region Handlers for Scene events - - private void HandleAddOrUpdateObjectInLocalScene(RegionSyncMessage msg) - { - // TODO: modify for physics - OSDMap data = DeserializeMessage(msg); + #region Handlers for Scene events + + private void HandleAddOrUpdateObjectInLocalScene(RegionSyncMessage msg) + { + // TODO: modify for physics + OSDMap data = DeserializeMessage(msg); /* if (data["locX"] == null || data["locY"] == null || data["sogXml"] == null) { m_log.Warn(LogHeader + ": parameters missing in NewObject/UpdatedObject message, need to have locX, locY, sogXml"); return; } - * */ - uint locX = data["locX"].AsUInteger(); - uint locY = data["locY"].AsUInteger(); - string sogxml = data["sogXml"].AsString(); - SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); - + * */ + uint locX = data["locX"].AsUInteger(); + uint locY = data["locY"].AsUInteger(); + string sogxml = data["sogXml"].AsString(); + SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); + } #endregion Handlers for events/updates from Scene diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index 8ea8bd6fb6..c82614a59c 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -44,6 +44,35 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //The connector that connects the local Scene (cache) and remote authoratative Scene public class PhysEngineToSceneConnectorModule : IRegionModule, IPhysEngineToSceneConnectorModule, ICommandableModule { + #region PhysEngineToSceneConnectorModule members and functions + + private static int m_activeActors = 0; + private bool m_active = false; + private string m_serveraddr; + private int m_serverport; + private Scene m_scene; + private ILog m_log; + private Object m_client_lock = new Object(); + //private PhysEngineToSceneConnector m_scriptEngineToSceneConnector = null; + private IConfig m_syncConfig = null; + public IConfig SyncConfig { get { return m_syncConfig; } } + private bool m_debugWithViewer = false; + public bool DebugWithViewer { get { return m_debugWithViewer; } } + private string m_regionSyncMode = ""; + + //Variables relavant for multi-scene subscription. + private Dictionary m_PEToSceneConnectors = new Dictionary(); //connector for each auth. scene + private string LogHeader = "[PhysEngineToSceneConnectorModule]"; + private PhysEngineToSceneConnector m_idlePEToSceneConnector = null; + + //quark information + //private int QuarkInfo.SizeX; + //private int QuarkInfo.SizeY; + //private string m_quarkListString; + private string m_subscriptionSpaceString; + + #endregion PhysEngineToSceneConnectorModule members and functions + #region IRegionModule Members public void Initialise(Scene scene, IConfigSource config) @@ -53,75 +82,30 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Read in configuration IConfig syncConfig = config.Configs["RegionSyncModule"]; - if (syncConfig != null && syncConfig.GetString("Enabled", "").ToLower() == "true") + if (syncConfig != null + && syncConfig.GetBoolean("Enabled", false) + && syncConfig.GetString("Mode", "").ToLower() == "client" + && syncConfig.GetBoolean("PhysEngineClient", false) + ) { scene.RegionSyncEnabled = true; } else { scene.RegionSyncEnabled = false; - } - - m_regionSyncMode = syncConfig.GetString("Mode", "").ToLower(); - if (syncConfig == null || m_regionSyncMode != "physics_engine") - { - m_log.Warn("[REGION SYNC PHYSICS ENGINE MODULE] Not in script_engine mode. Shutting down."); + m_log.Warn(LogHeader + ": Not in physics engine client mode. Shutting down."); return; } - //get the name of the valid region for script engine, i.e., that region that will holds all objects and scripts - //if not matching m_scene's name, simply return - string validLocalScene = syncConfig.GetString("ValidPhysEngineScene", ""); - if (!validLocalScene.Equals(scene.RegionInfo.RegionName)) - { - m_log.Warn("Not the valid local scene, shutting down"); - return; - } - m_active = true; - m_validLocalScene = validLocalScene; + m_active = true; + m_activeActors++; - m_log.Debug("Init PEToSceneConnectorModule, for local scene " + scene.RegionInfo.RegionName); + m_log.Debug(LogHeader + " Init PEToSceneConnectorModule, for local scene " + scene.RegionInfo.RegionName); - //get the number of regions this script engine subscribes - m_sceneNum = syncConfig.GetInt("SceneNumber", 1); - - //get the mapping of local scenes to auth. scenes - List authScenes = new List(); - for (int i = 0; i < m_sceneNum; i++) - { - string localScene = "LocalScene" + i; - string localSceneName = syncConfig.GetString(localScene, ""); - string masterScene = localScene + "Master"; - string masterSceneName = syncConfig.GetString(masterScene, ""); - - if (localSceneName.Equals("") || masterSceneName.Equals("")) - { - m_log.Warn(localScene + " or " + masterScene+ " has not been assigned a value in configuration. Shutting down."); - return; - } - - //m_localToAuthSceneMapping.Add(localSceneName, masterSceneName); - RecordLocalAuthSceneMappings(localSceneName, masterSceneName); - authScenes.Add(masterSceneName); - m_localScenesByName.Add(localSceneName, null); - } - - int defaultPort = 13000; - //get the addr:port info of the authoritative scenes - for (int i = 0; i < m_sceneNum; i++) - { - string authSceneName = authScenes[i]; - //string serverAddr = authSceneName + "_ServerIPAddress"; - //string serverPort = authSceneName + "_ServerPort"; - string serverAddr = authSceneName + "_SceneToPESyncServerIP"; - string addr = syncConfig.GetString(serverAddr, "127.0.0.1"); - string serverPort = authSceneName + "_SceneToPESyncServerPort"; - int port = syncConfig.GetInt(serverPort, defaultPort); - defaultPort++; - - AuthSceneInfo authSceneInfo = new AuthSceneInfo(authSceneName, addr, port); - m_authScenesInfoByName.Add(authSceneName, authSceneInfo); - } + string configString = scene.RegionInfo.RegionName + "_SceneToPESyncServerIP"; + m_serveraddr = syncConfig.GetString(configString, "127.0.0.1"); + configString = scene.RegionInfo.RegionName + "_SceneToPESyncServerPort"; + m_serverport = syncConfig.GetInt(configString, 13000); m_scene = scene; m_scene.RegisterModuleInterface(this); @@ -146,7 +130,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; InstallInterfaces(); - m_log.Warn("[REGION SYNC PHYSICS ENGINE MODULE] Initialised"); + m_log.Warn(LogHeader + " Initialised"); } public void PostInitialise() @@ -154,18 +138,17 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule if (!m_active) return; - //m_log.Warn("[REGION SYNC CLIENT MODULE] Post-Initialised"); - m_scene.EventManager.OnPopulateLocalSceneList += OnPopulateLocalSceneList; + //m_log.Warn(LogHeader + " Post-Initialised"); } public void Close() { if (m_active) { - m_scene.EventManager.OnPopulateLocalSceneList -= OnPopulateLocalSceneList; } m_scene = null; m_active = false; + m_activeActors--; } public string Name @@ -180,7 +163,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule #endregion #region ICommandableModule Members - private readonly Commander m_commander = new Commander("sync"); + private readonly Commander m_commander = new Commander("phys"); public ICommander CommandInterface { get { return m_commander; } @@ -206,323 +189,32 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } - - #endregion - - #region PhysEngineToSceneConnectorModule members and functions - - private bool m_active = false; - private string m_serveraddr; - private int m_serverport; - private Scene m_scene; - private ILog m_log; - private Object m_client_lock = new Object(); - //private PhysEngineToSceneConnector m_scriptEngineToSceneConnector = null; - private IConfig m_syncConfig = null; - private bool m_debugWithViewer = false; - private string m_regionSyncMode = ""; - - //Variables relavant for multi-scene subscription. - private int m_sceneNum = 0; - private string m_validLocalScene = ""; - private Dictionary m_localToAuthSceneMapping = new Dictionary(); //1-1 mapping from local shadow scene to authoratative scene - private Dictionary m_authToLocalSceneMapping = new Dictionary(); //1-1 mapping from authoratative scene to local shadow scene - private Dictionary m_localScenesByName = new Dictionary(); //name and references to local scenes - private Dictionary m_authScenesInfoByName = new Dictionary(); //info of each auth. scene's connector port, stored by each scene's name - private Dictionary m_PEToSceneConnectors = new Dictionary(); //connector for each auth. scene - private Dictionary m_authScenesInfoByLoc = new Dictionary(); //IP and port number of each auth. scene's connector port - private string LogHeader = "[PhysEngineToSceneConnectorModule]"; - private PhysEngineToSceneConnector m_idlePEToSceneConnector = null; - - //quark information - //private int QuarkInfo.SizeX; - //private int QuarkInfo.SizeY; - //private string m_quarkListString; - private string m_subscriptionSpaceString; - - public IConfig SyncConfig + public static bool IsPhysEngineScene { - get { return m_syncConfig; } + get { return SceneToPhysEngineSyncServer.IsPhysEngineScene; } } - - public bool DebugWithViewer + public static bool IsActivePhysEngineScene { - get { return m_debugWithViewer; } + get { return SceneToPhysEngineSyncServer.IsActivePhysEngineScene; } } - - //Record the locX and locY of one auth. scene (identified by addr:port) this PhysEngine connects to - public void RecordSceneLocation(string addr, int port, uint locX, uint locY) + public static bool IsPhysEngineActor { - string loc = SceneLocToString(locX, locY); - if (m_authScenesInfoByLoc.ContainsKey(loc)) - { - m_log.Warn(": have already registered info for Scene at " + loc); - m_authScenesInfoByLoc.Remove(loc); - } - - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - AuthSceneInfo authSceneInfo = valPair.Value; - if (authSceneInfo.Addr == addr && authSceneInfo.Port == port) - { - authSceneInfo.LocX = (int)locX; - authSceneInfo.LocY = (int)locY; - m_authScenesInfoByLoc.Add(loc, authSceneInfo); - break; - } - } - } - - /// - /// Set the property of a prim located in the given scene (identified by locX, locY) - /// - /// - /// - /// - /// - /// - public void SendSetPrimProperties(uint locX, uint locY, UUID primID, string pName, object pValue) - { - if (!Active || !Synced) - return; - - PhysEngineToSceneConnector connector = GetPEToSceneConnector(locX, locY); - connector.SendSetPrimProperties(primID, pName, pValue); - } - - public Scene GetLocalScene(string authSceneName) - { - if (!m_authToLocalSceneMapping.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": no authoritative scene with name "+authSceneName+" recorded"); - return null; - } - string localSceneName = m_authToLocalSceneMapping[authSceneName]; - if (m_localScenesByName.ContainsKey(localSceneName)) - { - return m_localScenesByName[localSceneName]; - } - else - return null; - } - - private string SceneLocToString(uint locX, uint locY) - { - string loc = locX + "-" + locY; - return loc; - } - - //Get the right instance of PhysEngineToSceneConnector, given the location of the authoritative scene - private PhysEngineToSceneConnector GetPEToSceneConnector(uint locX, uint locY) - { - string loc = SceneLocToString(locX, locY); - if (!m_authScenesInfoByLoc.ContainsKey(loc)) - return null; - string authSceneName = m_authScenesInfoByLoc[loc].Name; - if (!m_PEToSceneConnectors.ContainsKey(authSceneName)) - { - return null; - } - return m_PEToSceneConnectors[authSceneName]; - } - - - private void RecordLocalAuthSceneMappings(string localSceneName, string authSceneName) - { - if (m_localToAuthSceneMapping.ContainsKey(localSceneName)) - { - m_log.Warn(LogHeader + ": already registered " + localSceneName+", authScene was recorded as "+ m_localToAuthSceneMapping[localSceneName]); - } - else - { - m_localToAuthSceneMapping.Add(localSceneName, authSceneName); - } - if (m_authToLocalSceneMapping.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": already registered " + authSceneName + ", authScene was recorded as " + m_authToLocalSceneMapping[authSceneName]); - } - else - { - m_authToLocalSceneMapping.Add(authSceneName, localSceneName); - } - } - - //Get the name of the authoritative scene the given local scene maps to. Return null if not found. - private string GetAuthSceneName(string localSceneName) - { - if (m_localToAuthSceneMapping.ContainsKey(localSceneName)) - { - m_log.Warn(LogHeader + ": " + localSceneName + " not registered in m_localToAuthSceneMapping"); - return null; - } - return m_localToAuthSceneMapping[localSceneName]; - } - - //get the name of the local scene the given authoritative scene maps to. Return null if not found. - private string GetLocalSceneName(string authSceneName) - { - if (!m_authToLocalSceneMapping.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": " + authSceneName + " not registered in m_authToLocalSceneMapping"); - return null; - } - return m_authToLocalSceneMapping[authSceneName]; + get { return (m_activeActors != 0); } } #endregion + #region Event Handlers - - public void OnPopulateLocalSceneList(List localScenes) - //public void OnPopulateLocalSceneList(List localScenes, string[] cmdparams) - { - if (!Active) - return; - - //populate the dictionary m_localScenes - foreach (Scene lScene in localScenes) - { - string name = lScene.RegionInfo.RegionName; - if(!m_localScenesByName.ContainsKey(name)){ - m_log.Warn(LogHeader+": has not reigstered a local scene named "+name); - continue; - } - m_localScenesByName[name] = lScene; - - //lScene.RegionSyncMode = m_regionSyncMode; - lScene.IsOutsideScenes = IsOutSideSceneSubscriptions; - } - - //test position conversion - /* - //Vector3 pos = new Vector3(290, 100, 10); - uint preLocX = Convert.ToUInt32(cmdparams[2]); - uint preLocY = Convert.ToUInt32(cmdparams[3]); - float posX = (float)Convert.ToDouble(cmdparams[4]); - float posY = (float)Convert.ToDouble(cmdparams[5]); - float posZ = (float)Convert.ToDouble(cmdparams[6]); - Vector3 pos = new Vector3(posX, posY, posZ); - uint locX, locY; - Vector3 newPos; - ConvertPosition(1000, 1000, pos, out locX, out locY, out newPos); - * */ - } - #endregion - private string GetAllSceneNames() - { - string scenes = ""; - foreach (KeyValuePair valPair in m_localScenesByName) - { - Scene lScene = valPair.Value; - string authScene = m_localToAuthSceneMapping[lScene.RegionInfo.RegionName]; - scenes += authScene + ","; - - } - return scenes; - } - - //public bool IsOutSideSceneSubscriptions(Scene currentScene, Vector3 pos) - public bool IsOutSideSceneSubscriptions(uint locX, uint locY, Vector3 pos) - { - string sceneNames = GetAllSceneNames(); - m_log.Debug(LogHeader + ": IsOutSideSceneSubscriptions called. Conceptually, we are checking inside scene-subscriptions: " + sceneNames); - - //First, convert the position to a scene s.t. the attempting position is contained withing that scene - uint curLocX, curLocY; - Vector3 curPos; - bool converted = ConvertPosition(locX, locY, pos, out curLocX, out curLocY, out curPos); - - if (!converted) - { - m_log.Warn("("+locX+","+locY+","+pos+")"+" converts to scenes with negative coordinates."); - return false; - } - //See of the quark identified by (curLocX,curLocY) is one we subscribed to - string sceneLoc = SceneLocToString(curLocX, curLocY); - if (m_authScenesInfoByLoc.ContainsKey(sceneLoc)) - { - return false; - } - else - { - return true; - } - } - - //When the offset position is outside the range of current scene, convert it to the offset position in the right quark. - //Return null if the new scene's left-bottom corner X or Y value is negative. - //Assumption: A position is uniquely identified by (locX, locY, offsetPos). - private bool ConvertPosition(uint preLocX, uint preLocY, Vector3 prePos, out uint curLocX, out uint curLocY, out Vector3 curPos) - { - Vector3 newPos; - int newLocX; - int newLocY; - //code copied from EntityTransferModule.Cross() - - newPos = prePos; - newLocX = (int)preLocX; - newLocY = (int)preLocY; - - int changeX = 1; - int changeY = 1; - - //Adjust the X values, if going east, changeX is positive, otherwise, it is negative - if (prePos.X >= 0) - { - changeX = (int)(prePos.X / (int)Constants.RegionSize); - } - else - { - changeX = (int)(prePos.X / (int)Constants.RegionSize) - 1 ; - } - newLocX = (int)preLocX + changeX; - newPos.X = prePos.X - (changeX * Constants.RegionSize); - - if (prePos.Y >= 0) - { - changeY = (int)(prePos.Y / (int)Constants.RegionSize); - } - else - { - changeY = (int)(prePos.Y / (int)Constants.RegionSize) - 1; - } - changeY = (int)(prePos.Y / (int)Constants.RegionSize); - newLocY = (int)preLocY + changeY; - newPos.Y = prePos.Y - (changeY * Constants.RegionSize); - - curLocX = (uint)newLocX; - curLocY = (uint)newLocY; - curPos = newPos; - - if (newLocX < 0 || newLocY < 0) - { - //reset the position - curLocX = preLocX; - curLocY = preLocY; - if (newLocX < 0) - { - curPos.X = 2; - } - if(newLocY<0) - { - curPos.Y = 2; - } - return false; - } - else - return true; - } - - private void DebugSceneStats() { return; /* List avatars = m_scene.GetAvatars(); List entities = m_scene.GetEntities(); - m_log.WarnFormat("There are {0} avatars and {1} entities in the scene", avatars.Count, entities.Count); + m_log.WarnFormat("{0} There are {1} avatars and {2} entities in the scene", LogHeader, avatars.Count, entities.Count); */ } @@ -548,17 +240,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule cmdSyncSetQuarkSize.AddArgument("quarksizeX", "The size on x axis of each quark", "Integer"); cmdSyncSetQuarkSize.AddArgument("quarksizeY", "The size on y axis of each quark", "Integer"); - Command cmdSyncRegister = new Command("register", CommandIntentions.COMMAND_HAZARDOUS, SyncRegister, "Register as an idle script engine. Sync'ing with Scene won't start until \"sync start\". "); - - //For debugging load balancing and migration process - Command cmdSyncStartLB = new Command("startLB", CommandIntentions.COMMAND_HAZARDOUS, SyncStartLB, "Register as an idle script engine. Sync'ing with Scene won't start until \"sync start\". "); - m_commander.RegisterCommand("start", cmdSyncStart); m_commander.RegisterCommand("stop", cmdSyncStop); m_commander.RegisterCommand("status", cmdSyncStatus); m_commander.RegisterCommand("quarkSpace", cmdSyncSetQuarks); - m_commander.RegisterCommand("register", cmdSyncRegister); - m_commander.RegisterCommand("startLB", cmdSyncStartLB); lock (m_scene) { @@ -574,7 +259,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// Commandline arguments private void EventManager_OnPluginConsole(string[] args) { - if (args[0] == "sync") + if (args[0] == "phys") { if (args.Length == 1) { @@ -595,100 +280,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { lock (m_client_lock) { - //if (m_scriptEngineToSceneConnector != null) - if(m_PEToSceneConnectors.Count>0) - { - string authScenes = ""; - foreach (KeyValuePair valPair in m_PEToSceneConnectors) - { - authScenes += valPair.Key + ", "; - } - m_log.WarnFormat(LogHeader+": Already synchronized to "+authScenes); - return; - } - //m_log.Warn("[REGION SYNC CLIENT MODULE] Starting synchronization"); + //m_log.Warn(LogHeader + " Starting synchronization"); m_log.Warn(LogHeader + ": Starting RegionSyncPhysEngine"); - if (m_sceneNum > 1) - { - //If there is no arguments following "sync start", then be default we will connect to one or more scenes. - //we need to create a connector to each authoritative scene - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - string authSceneName = valPair.Key; - AuthSceneInfo authSceneInfo = valPair.Value; - - //create a new connector, the local end of each connector, however, is linked to the ValidScene only, - //since all objects will be contained in this scene only - PhysEngineToSceneConnector scriptEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, m_debugWithViewer, authSceneName, m_syncConfig); - if (scriptEngineToSceneConnector.Start()) - { - m_PEToSceneConnectors.Add(authSceneName, scriptEngineToSceneConnector); - } - } - } - else - { - //Only one remote scene to connect to. Subscribe to whatever specified in the config file. - //List quarkStringList = RegionSyncUtil.QuarkStringToStringList(m_quarkListString); - //InitPhysEngineToSceneConnector(quarkStringList); - InitPhysEngineToSceneConnector(m_subscriptionSpaceString); - } + //Only one remote scene to connect to. Subscribe to whatever specified in the config file. + //List quarkStringList = RegionSyncUtil.QuarkStringToStringList(m_quarkListString); + //InitPhysEngineToSceneConnector(quarkStringList); + InitPhysEngineToSceneConnector(m_subscriptionSpaceString); } } - private void SyncRegister(Object[] args) - { - //This should not happen. No-validLocalScene should not have register handlers for the command - //if (m_scene.RegionInfo.RegionName != m_validLocalScene) - // return; - - //Registration only, no state sync'ing yet. So only start the connector for the validLocalScene. (For now, we only test this with one scene, and - //quarks are smaller than a 256x256 scene. - string authSceneName = m_localToAuthSceneMapping[m_validLocalScene]; - AuthSceneInfo authSceneInfo = m_authScenesInfoByName[authSceneName]; - m_idlePEToSceneConnector = new PhysEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, m_debugWithViewer, authSceneName, m_syncConfig); - m_idlePEToSceneConnector.RegisterIdle(); - } - - /// - /// The given PhysEngineToSceneConnector, after having connected to the Scene (called its Start()), will - /// call this function to remove it self as an idle connector, and to be recorded as one working connector. - /// - /// - public void RecordSyncStartAfterLoadMigration(PhysEngineToSceneConnector seToSceneConnector) - { - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - string authSceneName = valPair.Key; - AuthSceneInfo authSceneInfo = valPair.Value; - - string localScene = m_authToLocalSceneMapping[authSceneName]; - - if (localScene != m_scene.RegionInfo.RegionName) - continue; - - if (m_PEToSceneConnectors.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": Connector to " + authSceneName + " is already considered connected"); - return; - } - - m_PEToSceneConnectors.Add(authSceneName, seToSceneConnector); - //there should only be one element in the dictionary if we reach this loop, anyway, we break from it. - break; - } - m_idlePEToSceneConnector = null; - } - - private void SyncStartLB(Object[] args) - { - string authSceneName = m_localToAuthSceneMapping[m_validLocalScene]; - PhysEngineToSceneConnector sceneConnector = m_PEToSceneConnectors[authSceneName]; - // TODO: load balancing. Next line commented out - // sceneConnector.SendLoadBalanceRequest(); - } - private void SetQuarkList(Object[] args) { m_subscriptionSpaceString = (string)args[0]; @@ -706,26 +307,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private void InitPhysEngineToSceneConnector(string space) { - foreach (KeyValuePair valPair in m_authScenesInfoByName) + PhysEngineToSceneConnector scriptEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, + m_serveraddr, m_serverport, m_debugWithViewer, /* space,*/ m_syncConfig); + if (scriptEngineToSceneConnector.Start()) { - string authSceneName = valPair.Key; - AuthSceneInfo authSceneInfo = valPair.Value; - - string localScene = m_authToLocalSceneMapping[authSceneName]; - - if (localScene != m_scene.RegionInfo.RegionName) - continue; - - //create a new connector, the local end of each connector, however, is set of the ValidScene only, - //since all objects will be contained in this scene only - PhysEngineToSceneConnector scriptEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, - m_debugWithViewer, authSceneName, space, m_syncConfig); - if (scriptEngineToSceneConnector.Start()) - { - m_PEToSceneConnectors.Add(authSceneName, scriptEngineToSceneConnector); - } - - break; //there should only be one element in the dictionary if we reach this loop, anyway, we break from it. + m_PEToSceneConnectors.Add(m_scene.RegionInfo.RegionName, scriptEngineToSceneConnector); } } @@ -736,7 +322,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //if (m_scriptEngineToSceneConnector == null) if(m_PEToSceneConnectors.Count==0 && m_idlePEToSceneConnector==null) { - m_log.WarnFormat("[REGION SYNC PHYSICS ENGINE MODULE] Already stopped"); + m_log.Warn(LogHeader + " Already stopped"); return; } @@ -764,8 +350,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.Warn(LogHeader+": Stopping synchronization"); } - m_authScenesInfoByLoc.Clear(); - //save script state and stop script instances // TODO: Load balancing. next line commented out to compile // m_scene.EventManager.TriggerPhysEngineSyncStop(); @@ -780,10 +364,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { if (m_PEToSceneConnectors.Count == 0) { - m_log.WarnFormat("[REGION SYNC PHYSICS ENGINE MODULE] Not currently synchronized"); + m_log.Warn(LogHeader + " Not currently synchronized"); return; } - m_log.WarnFormat("[REGION SYNC PHYSICS ENGINE MODULE] Synchronized"); + m_log.Warn(LogHeader + " Synchronized"); foreach (KeyValuePair pair in m_PEToSceneConnectors) { PhysEngineToSceneConnector sceneConnector = pair.Value; diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs index 4f6899de58..ebed0d7bf3 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs @@ -109,6 +109,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_seSyncServerport = syncConfig.GetInt(seServerPort, DefaultPort); DefaultPort++; + //Get sync server info for Physics Engine actors + string peServerAddr = scene.RegionInfo.RegionName + "_SceneToPESyncServerIP"; + m_peSyncServeraddr = syncConfig.GetString(peServerAddr, "127.0.0.1"); + string peServerPort = scene.RegionInfo.RegionName + "_SceneToPESyncServerPort"; + m_peSyncServerport = syncConfig.GetInt(peServerPort, DefaultPort); + DefaultPort++; + //Get quark information QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); @@ -154,6 +161,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Start the sync server for script engines m_sceneToSESyncServer = new SceneToScriptEngineSyncServer(m_scene, m_seSyncServeraddr, m_seSyncServerport); m_sceneToSESyncServer.Start(); + + m_log.Warn("[REGION SYNC SERVER MODULE] Starting SceneToPhysEngineSyncServer"); + //Start the sync server for physics engines + m_sceneToPESyncServer = new SceneToPhysEngineSyncServer(m_scene, m_peSyncServeraddr, m_peSyncServerport); + m_sceneToPESyncServer.Start(); //m_log.Warn("[REGION SYNC SERVER MODULE] Post-Initialised"); } @@ -489,6 +501,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private string m_seSyncServeraddr; private int m_seSyncServerport; private SceneToScriptEngineSyncServer m_sceneToSESyncServer = null; + + //Sync-server for physics engine + private string m_peSyncServeraddr; + private int m_peSyncServerport; + private SceneToPhysEngineSyncServer m_sceneToPESyncServer = null; //quark related information //private int QuarkInfo.SizeX; diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index 44f64e5bef..f5390f480d 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -41,7 +41,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //Here is the per actor type listening server for physics Engines. - public class SceneToPhysEngineSyncServer + public class SceneToPhysEngineSyncServer : ISceneToPhysEngineServer { #region SceneToPhysEngineSyncServer members // Set the addr and port for TcpListener @@ -58,6 +58,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private int peCounter; + // static counters that are used to compute global configuration state + private static int m_syncServerInitialized = 0; + private static int m_totalConnections = 0; + // The local scene. private Scene m_scene; @@ -92,6 +96,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return (m_physEngineConnectors.Count > 0); } } + public static bool IsPhysEngineScene + { + get { return (m_syncServerInitialized != 0); } + } + public static bool IsActivePhysEngineScene + { + get { return (m_syncServerInitialized != 0 && m_totalConnections != 0); } + } + public static bool IsPhysEngineActor + { + get { return PhysEngineToSceneConnectorModule.IsPhysEngineActor; } + } + #endregion // Constructor @@ -130,6 +147,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.WarnFormat(LogHeader + ": Starting {0} thread", m_listenerThread.Name); m_listenerThread.Start(); //m_log.Warn("[REGION SYNC SERVER] Started"); + m_syncServerInitialized++; } @@ -137,6 +155,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Stop the server and disconnect all RegionSyncClients public void Shutdown() { + m_syncServerInitialized--; // Stop the listener and listening thread so no new clients are accepted m_listener.Stop(); m_listenerThread.Abort(); diff --git a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs index 45573e504b..3d30a45f3e 100755 --- a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs @@ -36,18 +36,9 @@ namespace OpenSim.Region.Framework.Interfaces //the interface for Scene to sync with Script Engine public interface IPhysEngineToSceneConnectorModule { - bool Active { get; } - bool Synced { get; } + // static bool IsPhysEngineScene { get; } + // static bool IsActivePhysEngineScene { get; } + // static bool IsPhysEngineActor { get; } bool DebugWithViewer { get; } - //void SendCoarseLocations(); - /// - /// Update the property of prim with primID, where the prim is located at quark (LocX, LocY). The length of each quark is configurable. - /// - /// - /// - /// - /// - /// - void SendSetPrimProperties(uint locX, uint locY, UUID primID, string pName, object pValue); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9cd6db8160..7a0d6c52e6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -410,37 +410,31 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_physEngineToSceneConnectorModule; } set { m_physEngineToSceneConnectorModule = value; } - } - - // list of physactors for this scene so we can find them later for remote physics - public Dictionary PhysActors = new Dictionary(); - public void AddPhysActor(uint id, PhysicsActor pActor) - { - if (PhysActors.ContainsKey(id)) { - PhysActors.Remove(id); - } - PhysActors.Add(id, pActor); - return; - } - public void RemovePhysActor(uint id) - { - if (PhysActors.ContainsKey(id)) { - PhysActors.Remove(id); - } - return; - } - - public bool IsPhysEngineScene() - { - return (SceneToPhysEngineConnectorModule != null); - } - public bool IsActivePhysEngineScene() - { - return (SceneToPhysEngineConnectorModule != null && SceneToPhysEngineConnectorModule.Active); - } - public bool IsPhysEngineActor() - { - return (PhysEngineToSceneConnectorModule != null); + } + + protected ISceneToPhysEngineServer m_sceneToPhysEngineSyncServer = null; + public ISceneToPhysEngineServer SceneToPhysEngineSyncServer + { + get { return m_sceneToPhysEngineSyncServer; } + set { m_sceneToPhysEngineSyncServer = value; } + } + + // list of physactors for this scene so we can find them later for remote physics + public Dictionary PhysActors = new Dictionary(); + public void AddPhysActor(uint id, PhysicsActor pActor) + { + if (PhysActors.ContainsKey(id)) { + PhysActors.Remove(id); + } + PhysActors.Add(id, pActor); + return; + } + public void RemovePhysActor(uint id) + { + if (PhysActors.ContainsKey(id)) { + PhysActors.Remove(id); + } + return; } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -1480,6 +1474,8 @@ namespace OpenSim.Region.Framework.Scenes RegionSyncServerModule = RequestModuleInterface(); RegionSyncClientModule = RequestModuleInterface(); ScriptEngineToSceneConnectorModule = RequestModuleInterface(); + PhysEngineToSceneConnectorModule = RequestModuleInterface(); + SceneToPhysEngineSyncServer = RequestModuleInterface(); // Shoving this in here for now, because we have the needed // interfaces at this point diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 67fb6fe791..376019f549 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1585,8 +1585,8 @@ namespace OpenSim.Region.Framework.Scenes dupe.RootPart.RotationOffset, dupe.RootPart.PhysActor.IsPhysical); - dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; - // RA: Register physActor in scene + dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + // RA: Register physActor in scene dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); } @@ -2389,8 +2389,8 @@ namespace OpenSim.Region.Framework.Scenes linkPart.LinkNum = 0; if (linkPart.PhysActor != null) - { - m_scene.RemovePhysActor(linkPart.PhysActor.LocalID); + { + m_scene.RemovePhysActor(linkPart.PhysActor.LocalID); m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b797ef78d0..46ac996a96 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1491,9 +1491,9 @@ 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.LocalID = LocalId; - // RA: register PhysActor with the scene - ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); + PhysActor.LocalID = LocalId; + // RA: register PhysActor with the scene + ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); DoPhysicsPropertyUpdate(RigidBody, true); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } @@ -4311,9 +4311,9 @@ namespace OpenSim.Region.Framework.Scenes pa = PhysActor; if (pa != null) { - pa.LocalID = LocalId; - // RA: register PhysActor with scene - ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); + pa.LocalID = LocalId; + // RA: register PhysActor with scene + ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index aa43e97be1..8fbc8cd9f2 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -140,9 +140,9 @@ namespace OpenSim.Region.Physics.Manager public abstract Vector3 Size { get; set; } - public abstract PrimitiveBaseShape Shape { set; } - - // RA: used to be abstract but changed to allow 'get' without changing all the phys engines + public abstract PrimitiveBaseShape Shape { set; } + + // RA: used to be abstract but changed to allow 'get' without changing all the phys engines public virtual uint LocalID { set { return; } get { return 0; } } public abstract bool Grabbed { set; } @@ -158,8 +158,8 @@ namespace OpenSim.Region.Physics.Manager public abstract void delink(); - public abstract void LockAngularMotion(Vector3 axis); - + public abstract void LockAngularMotion(Vector3 axis); + public virtual void RequestPhysicsterseUpdate() { // Make a temporary copy of the event to avoid possibility of @@ -280,7 +280,7 @@ namespace OpenSim.Region.Physics.Manager public override uint LocalID { - set { return; } + set { return; } get { return 0; } } diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 6a6c03eab2..e41f15a4e2 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -26,13 +26,16 @@ using System; using System.Reflection; using System.Collections.Generic; +using System.Xml; using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; +using OpenSim.Region.CoreModules.RegionSync.RegionSyncModule; namespace OpenSim.Region.Physics.PEPlugin { + [Serializable] public sealed class PEPrim : PhysicsActor { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -98,7 +101,7 @@ public sealed class PEPrim : PhysicsActor set { _localID = value; m_log.Debug("[RPE] PEPrim set LocalID"); Prop.Set(_localID, PropType.LocalID, _localID); - } + } get { return _localID; } } public override bool Grabbed { diff --git a/prebuild.xml b/prebuild.xml index 5716295935..2278e76ff9 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -533,6 +533,7 @@ + @@ -560,9 +561,11 @@ ../../../../bin/ + + From 5c6f0878a18f6a63d0995934887d1f19b83dc3bf Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 6 Dec 2010 10:58:54 -0800 Subject: [PATCH 04/15] Add interfaces for physEngine connectors --- .../Interfaces/IPhysEngineToSceneConnector.cs | 41 ++++++++++++++++++ .../Interfaces/ISceneToPhysEngineConnector.cs | 41 ++++++++++++++++++ .../Interfaces/ISceneToPhysEngineServer.cs | 43 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100755 OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnector.cs create mode 100755 OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineConnector.cs create mode 100755 OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs diff --git a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnector.cs b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnector.cs new file mode 100755 index 0000000000..0b818ff842 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnector.cs @@ -0,0 +1,41 @@ +/* + * 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 OpenSim 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. + */ + +//KittyL: Added to support running script engine actor + +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.Interfaces +{ + //the interface for Scene to sync with Script Engine + public interface IPhysEngineToSceneConnector + { + // TODO: + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineConnector.cs b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineConnector.cs new file mode 100755 index 0000000000..7f5fab6fc5 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineConnector.cs @@ -0,0 +1,41 @@ +/* + * 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 OpenSim 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. + */ + +//KittyL: Added to support running script engine actor + +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.Interfaces +{ + //the interface for Scene to sync with Script Engine + public interface ISceneToPhysEngineConnector + { + // TODO: + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs new file mode 100755 index 0000000000..1526c00a0d --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.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 OpenSim 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. + */ + +//KittyL: Added to support running script engine actor + +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.Interfaces +{ + //the interface for Scene to sync with Script Engine + public interface ISceneToPhysEngineServer + { + // static bool IsPhysEngineScene { get; } + // static bool IsActivePhysEngineScene { get; } + // static bool IsPhysEngineActor { get; } + } +} \ No newline at end of file From a036426f18414d333542d7700d7e137b4ce43e3c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 8 Dec 2010 17:19:06 -0800 Subject: [PATCH 05/15] PhysActor update messages working. Avatar and prim neither move nor position correctly --- .../PhysEngineToSceneConnector.cs | 161 +++++++------- .../PhysEngineToSceneConnectorModule.cs | 63 +++++- .../RegionSyncModule/RegionSyncMessage.cs | 6 + .../SceneToPhysEngineConnector.cs | 119 ++++++++++- .../SceneToPhysEngineSyncServer.cs | 200 ++++++++++++++++-- .../IPhysEngineToSceneConnectorModule.cs | 2 + .../Interfaces/ISceneToPhysEngineServer.cs | 2 + OpenSim/Region/Framework/Scenes/Scene.cs | 28 +-- .../Framework/Scenes/SceneObjectGroup.cs | 3 - .../Framework/Scenes/SceneObjectPart.cs | 6 - .../Region/Physics/Manager/PhysicsActor.cs | 34 +++ .../Region/Physics/OdePlugin/ODECharacter.cs | 14 ++ OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 24 ++- .../Region/Physics/PEPlugin/PECharacter.cs | 7 +- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 3 + OpenSim/Region/Physics/PEPlugin/PEScene.cs | 26 +++ bin/OpenSim.32BitLaunch.pdb | Bin 13824 -> 11776 bytes prebuild.xml | 4 + 18 files changed, 555 insertions(+), 147 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 4680dc50e0..8631af58f5 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -12,6 +12,7 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Services.Interfaces; using OpenSim.Framework.Client; +using OpenSim.Region.Physics.Manager; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Interfaces; @@ -74,6 +75,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private ActorType m_actorType = ActorType.PhysicsEngine; private bool m_debugWithViewer = false; + private long m_messagesSent = 0; + private long m_messagesReceived = 0; private QuarkSubsriptionInfo m_subscribedQuarks; @@ -165,7 +168,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStatus, Convert.ToString((int)ActorStatus.Sync)); Send(msg); - SendQuarkSubscription(); + // SendQuarkSubscription(); Thread.Sleep(100); DoInitialSync(); } @@ -196,7 +199,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private void DoInitialSync() { - m_validLocalScene.DeleteAllSceneObjects(); + // m_validLocalScene.DeleteAllSceneObjects(); //m_log.Debug(LogHeader + ": send actor type " + m_actorType); //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorType, Convert.ToString((int)m_actorType))); //KittyL??? Do we need to send in RegionName? @@ -204,8 +207,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName)); //m_log.WarnFormat("Sending region name: \"{0}\"", m_scene.RegionInfo.RegionName); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain)); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects)); + // Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain)); + // Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects)); // Register for events which will be forwarded to authoritative scene // m_scene.EventManager.OnNewClient += EventManager_OnNewClient; @@ -229,6 +232,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void ReportStatus() { m_log.WarnFormat("{0} Synchronized to RegionSyncServer at {1}:{2}", LogHeader, m_addr, m_port); + m_log.WarnFormat("{0} Received={1}, Sent={2}", LogHeader, m_messagesReceived, m_messagesSent); lock (m_syncRoot) { //TODO: should be reporting about the information of the objects/scripts @@ -278,6 +282,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule try { //lock (m_syncRoot) -- KittyL: why do we need to lock here? We could lock inside HandleMessage if necessary, and lock on different objects for better performance + m_messagesReceived++; HandleMessage(msg); } catch (Exception e) @@ -310,6 +315,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule try { m_client.GetStream().Write(data, 0, data.Length); + m_messagesSent++; } // If there is a problem reading from the client, shut 'er down. // *** Still need to alert the module that it's no longer connected! @@ -319,79 +325,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } } - - /// - /// Send requests to update object properties in the remote authoratative Scene. - /// - /// UUID of the object - /// name of the property to be updated - /// parameters of the value of the property - /// - public void SendSetPrimProperties(UUID primID, string pName, object val) - { - OSDMap data = new OSDMap(); - data["UUID"] = OSD.FromUUID(primID); - data["name"] = OSD.FromString(pName); - object[] valParams = (object[])val; - //data["param"] = OSD.FromString(presence.ControllingClient.LastName); - Vector3 pos, vel; - switch (pName) - { - case "object_rez": - //this is to rez an object from the prim's inventory, rather than change the prim's property - if(valParams.Length<5){ - m_log.Warn(LogHeader+": values for object's "+pName+" property should include: inventory, pos, velocity, rotation, param"); - return; - } - string inventory = (string)valParams[0]; - pos = (Vector3)valParams[1]; - vel = (Vector3)valParams[2]; - Quaternion rot = (Quaternion)valParams[3]; - int param = (int)valParams[4]; - data["inventory"]=OSD.FromString(inventory); - data["pos"]=OSD.FromVector3(pos); - data["vel"] = OSD.FromVector3(vel); - data["rot"] = OSD.FromQuaternion(rot); - data["param"] = OSD.FromInteger(param); - break; - case "color": - if(valParams.Length<2){ - m_log.Warn(LogHeader+": values for object's "+pName+" property should include: color-x, color-y, color-z, face"); - return; - } - //double cx = (double)valParams[0]; - //double cy = (double)valParams[1]; - //double cz = (double)valParams[2]; - //Vector3 color = new Vector3((float)cx, (float)cy, (float)cz); - Vector3 color = (Vector3)valParams[0]; - data["color"] = OSD.FromVector3(color); - data["face"] = OSD.FromInteger((int)valParams[1]); - - //m_log.DebugFormat("{0}: to set color {1} on face {2} of prim {3}", LogHeader, color.ToString(), (int)valParams[1], primID); - - break; - case "pos": - if (valParams.Length < 1) - { - m_log.Warn(LogHeader + ": values for object's " + pName + " property should include: pos(vector)"); - return; - } - //double px = (double)valParams[0]; - //double py = (double)valParams[1]; - //double pz = (double)valParams[2]; - //Vector3 pos = new Vector3((float)px, (float)py, (float)pz); - pos = (Vector3)valParams[0]; - data["pos"] = OSD.FromVector3(pos); - - m_log.DebugFormat("{0}: to set pos {1} for prim {2}", LogHeader, pos.ToString(), primID); - break; - default: - // - break; - } - - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.SetObjectProperty, OSDParser.SerializeJsonString(data))); - } #endregion SEND //KittyL: Has to define SendCoarseLocations() here, since it's defined in IRegionSyncClientModule. @@ -415,16 +348,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { return; } - case RegionSyncMessage.MsgType.Terrain: + case RegionSyncMessage.MsgType.PhysUpdateAttributes: { - //We need to handle terrain differently as we handle objects: we really will set the HeightMap - //of each local scene that is the shadow copy of its auth. scene. - return; - } - case RegionSyncMessage.MsgType.NewObject: - case RegionSyncMessage.MsgType.UpdatedObject: - { - HandleAddOrUpdateObjectInLocalScene(msg); + HandlePhysUpdateAttributes(msg); return; } default: @@ -436,6 +362,69 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } + /// + /// The physics engine has some updates to the attributes. Unpack the parameters, find the + /// correct PhysicsActor and plug in the new values; + /// + /// + private void HandlePhysUpdateAttributes(RegionSyncMessage msg) + { + // TODO: + OSDMap data = RegionSyncUtil.DeserializeMessage(msg, LogHeader); + try + { + uint localID = data["localID"].AsUInteger(); + // m_log.DebugFormat("{0}: HandlPhysUpdateAttributes for {1}", LogHeader, localID); + SceneObjectPart sop = m_validLocalScene.GetSceneObjectPart(localID); + if (sop != null) + { + sop.PhysActor.Size = data["size"].AsVector3(); + sop.PhysActor.Position = data["position"].AsVector3(); + sop.PhysActor.Force = data["force"].AsVector3(); + sop.PhysActor.Velocity = data["velocity"].AsVector3(); + sop.PhysActor.Torque = data["torque"].AsVector3(); + sop.PhysActor.Orientation = data["orientantion"].AsQuaternion(); + sop.PhysActor.IsPhysical = data["isPhysical"].AsBoolean(); // receive?? + sop.PhysActor.Flying = data["flying"].AsBoolean(); // receive?? + sop.PhysActor.Kinematic = data["kinematic"].AsBoolean(); // receive?? + sop.PhysActor.Buoyancy = (float)(data["buoyancy"].AsReal()); + sop.PhysActor.Shape = sop.Shape; + } + else + { + m_log.WarnFormat("{0}: attribute update for unknown localID {1}", LogHeader, localID); + return; + } + } + catch (Exception e) + { + m_log.WarnFormat("{0}: EXCEPTION processing UpdateAttributes: {1}", LogHeader, e); + return; + } + return; + } + + public void SendPhysUpdateAttributes(PhysicsActor pa) + { + m_log.DebugFormat("{0}: SendPhysUpdateAttributes for {1}", LogHeader, pa.LocalID); + OSDMap data = new OSDMap(9); + data["localID"] = OSD.FromUInteger(pa.LocalID); + data["size"] = OSD.FromVector3(pa.Size); + data["position"] = OSD.FromVector3(pa.Position); + data["force"] = OSD.FromVector3(pa.Force); + data["velocity"] = OSD.FromVector3(pa.Velocity); + data["torque"] = OSD.FromVector3(pa.Torque); + data["orientation"] = OSD.FromQuaternion(pa.Orientation); + data["isPhysical"] = OSD.FromBoolean(pa.IsPhysical); + data["flying"] = OSD.FromBoolean(pa.Flying); + data["buoyancy"] = OSD.FromReal(pa.Buoyancy); + + RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.PhysUpdateAttributes, + OSDParser.SerializeJsonString(data)); + Send(rsm); + return; + } + #region Utility functions private OSDMap GetOSDMap(string strdata) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index c82614a59c..2359fdfb6b 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -35,6 +35,7 @@ using OpenSim.Framework.Client; using OpenSim.Region.CoreModules.Framework.InterfaceCommander; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; using log4net; using System.Net; using System.Net.Sockets; @@ -51,6 +52,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private string m_serveraddr; private int m_serverport; private Scene m_scene; + private static List m_allScenes = new List(); private ILog m_log; private Object m_client_lock = new Object(); //private PhysEngineToSceneConnector m_scriptEngineToSceneConnector = null; @@ -64,6 +66,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private Dictionary m_PEToSceneConnectors = new Dictionary(); //connector for each auth. scene private string LogHeader = "[PhysEngineToSceneConnectorModule]"; private PhysEngineToSceneConnector m_idlePEToSceneConnector = null; + private PhysEngineToSceneConnector m_physEngineToSceneConnector = null; //quark information //private int QuarkInfo.SizeX; @@ -131,6 +134,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule InstallInterfaces(); m_log.Warn(LogHeader + " Initialised"); + + // collect all the scenes for later routing + if (!m_allScenes.Contains(scene)) + { + m_allScenes.Add(scene); + } } public void PostInitialise() @@ -202,6 +211,49 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return (m_activeActors != 0); } } + /// + /// The scene is unknown by ODE so we have to look through the scenes to + /// find the one with this PhysicsActor so we can send the update. + /// + /// + public static void RouteUpdate(PhysicsActor pa) + { + SceneObjectPart sop = null; + Scene s = null; + foreach (Scene ss in m_allScenes) + { + try + { + sop = ss.GetSceneObjectPart(pa.LocalID); + } + catch + { + sop = null; + } + if (sop != null) + { + s = ss; + break; + } + } + if (s != null) + { + if (s.PhysEngineToSceneConnectorModule != null) + { + s.PhysEngineToSceneConnectorModule.SendUpdate(pa); + } + else + { + Console.WriteLine("RouteUpdate: PhysEngineToSceneConnectorModule is null"); + } + } + else + { + Console.WriteLine("RouteUpdate: no SOP found"); + } + return; + } + #endregion @@ -218,6 +270,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule */ } + public void SendUpdate(PhysicsActor pa) + { + this.m_physEngineToSceneConnector.SendPhysUpdateAttributes(pa); + } + #region Console Command Interface //IMPORTANT: these functions should only be actived for the PhysEngineToSceneConnectorModule that is associated with the valid local scene @@ -307,11 +364,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private void InitPhysEngineToSceneConnector(string space) { - PhysEngineToSceneConnector scriptEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, + m_physEngineToSceneConnector = new PhysEngineToSceneConnector(m_scene, m_serveraddr, m_serverport, m_debugWithViewer, /* space,*/ m_syncConfig); - if (scriptEngineToSceneConnector.Start()) + if (m_physEngineToSceneConnector.Start()) { - m_PEToSceneConnectors.Add(m_scene.RegionInfo.RegionName, scriptEngineToSceneConnector); + m_PEToSceneConnectors.Add(m_scene.RegionInfo.RegionName, m_physEngineToSceneConnector); } } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs index f2da4d636d..0f1324172f 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs @@ -108,6 +108,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule ScriptStateSyncEnd, //Idle script engine overloaded -> overloaded script engine ScriptStateSyncRequest, + // Physics Engine -> Scene + PhysTerseUpdate, + PhysOutOfBounds, + PhysCollisionUpdate, + // Scene -> Physics Engine + PhysUpdateAttributes, } #endregion diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index 86054428a4..e2772fe776 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -12,6 +12,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Physics.Manager; using log4net; namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule @@ -94,7 +95,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public string GetStats() { - int syncedAvCount; string ret; //lock (m_syncRoot) // syncedAvCount = m_syncedAvatars.Count; @@ -103,7 +103,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule double secondsSinceLastStats = DateTime.Now.Subtract(lastStatTime).TotalSeconds; lastStatTime = DateTime.Now; - ret = String.Format("[{0,4}/{1,4}], [{2,4}/{3,4}], [{4,4}/{5,4}], [{6,4} ({7,4})], [{8,8} ({9,8:00.00})], [{10,4} ({11,4})], [{12,8} ({13,8:00.00})], [{14,8} ({15,4}]", + // ret = String.Format("[{0,4}/{1,4}], [{2,4}/{3,4}], [{4,4}/{5,4}], [{6,4} ({7,4})], [{8,8} ({9,8:00.00})], [{10,4} ({11,4})], [{12,8} ({13,8:00.00})], [{14,8} ({15,4}]", + ret = String.Format("[{0,4}/{1,4}], [{2,6}/{3,6}], [{4,4}/{5,4}], [{6,6} ({7,6})], [{8,4} ({9,4})]", //lastTotalCount, totalAvCount, // TOTAL AVATARS //lastLocalCount, syncedAvCount, // LOCAL TO THIS CLIENT VIEW //lastRemoteCount, totalAvCount - syncedAvCount, // REMOTE (SHOULD = TOTAL - LOCAL) @@ -162,7 +163,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_receive_loop.Start(); //tell the remote script engine about the locX, locY of this authoritative scene - SendSceneLoc(); + // SendSceneLoc(); + m_log.DebugFormat("{0}: SceneToPhysEngineConnector initialized", LogHeader); } // Stop the listening thread, disconnecting the RegionSyncPhysEngine @@ -257,7 +259,27 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } return; } - + + case RegionSyncMessage.MsgType.PhysTerseUpdate: + { + HandlePhysTerseUpdate(msg); + return; + } + case RegionSyncMessage.MsgType.PhysOutOfBounds: + { + HandlePhysOutOfBounds(msg); + return; + } + case RegionSyncMessage.MsgType.PhysCollisionUpdate: + { + HandlePhysCollisionUpdate(msg); + return; + } + case RegionSyncMessage.MsgType.PhysUpdateAttributes: + { + HandlePhysUpdateAttributes(msg); + return; + } default: { m_log.WarnFormat("{0} Unable to handle unsupported message type", LogHeader); @@ -266,6 +288,86 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } + private void HandlePhysTerseUpdate(RegionSyncMessage msg) + { + // TODO: + return; + } + + private void HandlePhysOutOfBounds(RegionSyncMessage msg) + { + // TODO: + return; + } + + private void HandlePhysCollisionUpdate(RegionSyncMessage msg) + { + // TODO: + return; + } + + /// + /// The physics engine has some updates to the attributes. Unpack the parameters, find the + /// correct PhysicsActor and plug in the new values; + /// + /// + private void HandlePhysUpdateAttributes(RegionSyncMessage msg) + { + // TODO: + OSDMap data = RegionSyncUtil.DeserializeMessage(msg, LogHeader); + try + { + uint localID = data["localID"].AsUInteger(); + m_log.DebugFormat("{0}: received PhysUpdateAttributes for {1}", LogHeader, localID); + SceneObjectPart sop = m_scene.GetSceneObjectPart(localID); + if (sop != null) + { + sop.PhysActor.Size = data["size"].AsVector3(); + sop.PhysActor.Position = data["position"].AsVector3(); + sop.PhysActor.Force = data["force"].AsVector3(); + sop.PhysActor.Velocity = data["velocity"].AsVector3(); + sop.PhysActor.Torque = data["torque"].AsVector3(); + sop.PhysActor.Orientation = data["orientantion"].AsQuaternion(); + sop.PhysActor.IsPhysical = data["isPhysical"].AsBoolean(); // receive?? + sop.PhysActor.Flying = data["flying"].AsBoolean(); // receive?? + sop.PhysActor.Kinematic = data["kinematic"].AsBoolean(); // receive?? + sop.PhysActor.Buoyancy = (float)(data["buoyancy"].AsReal()); + } + else + { + m_log.WarnFormat("{0}: attribute update for unknown localID {1}", LogHeader, localID); + return; + } + } + catch (Exception e) + { + m_log.WarnFormat("{0}: EXCEPTION processing UpdateAttributes: {1}", LogHeader, e); + return; + } + return; + } + + public void SendPhysUpdateAttributes(PhysicsActor pa) + { + // m_log.DebugFormat("{0}: sending PhysUpdateAttributes for {1}", LogHeader, pa.LocalID); + OSDMap data = new OSDMap(9); + data["localID"] = OSD.FromUInteger(pa.LocalID); + data["size"] = OSD.FromVector3(pa.Size); + data["position"] = OSD.FromVector3(pa.Position); + data["force"] = OSD.FromVector3(pa.Force); + data["velocity"] = OSD.FromVector3(pa.Velocity); + data["torque"] = OSD.FromVector3(pa.Torque); + data["orientation"] = OSD.FromQuaternion(pa.Orientation); + data["isPhysical"] = OSD.FromBoolean(pa.IsPhysical); + data["flying"] = OSD.FromBoolean(pa.Flying); + data["buoyancy"] = OSD.FromReal(pa.Buoyancy); + + RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.PhysUpdateAttributes, + OSDParser.SerializeJsonString(data)); + Send(rsm); + return; + } + //For simplicity, we assume the subscription sent by PhysEngine is legistimate (no overlapping with other script engines, etc) private void HandleQuarkSubscription(RegionSyncMessage msg) { @@ -335,7 +437,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_tcpclient.GetStream().EndWrite(ar); } catch (Exception) - { } + { + m_log.WarnFormat("{0} Write to output stream failed", LogHeader); + } } }, null); } @@ -344,6 +448,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.WarnFormat("{0} Physics Engine has disconnected.", LogHeader); } } + else + { + m_log.DebugFormat("{0} Attempt to send with no connection", LogHeader); + } + } public void SendObjectUpdate(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index f5390f480d..4dc0cc5ed0 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -6,6 +6,7 @@ using System.Text; using System.Collections.Generic; using System.Threading; using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.InterfaceCommander; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; using log4net; @@ -13,6 +14,7 @@ using log4net; using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { @@ -41,7 +43,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //Here is the per actor type listening server for physics Engines. - public class SceneToPhysEngineSyncServer : ISceneToPhysEngineServer + public class SceneToPhysEngineSyncServer : ISceneToPhysEngineServer, ICommandableModule { #region SceneToPhysEngineSyncServer members // Set the addr and port for TcpListener @@ -61,6 +63,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // static counters that are used to compute global configuration state private static int m_syncServerInitialized = 0; private static int m_totalConnections = 0; + private static List m_allScenes = new List(); // The local scene. private Scene m_scene; @@ -74,6 +77,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private object m_physEngineConnector_lock = new object(); //private Dictionary m_physEngineConnectors = new Dictionary(); private List m_physEngineConnectors = new List(); + // the last connector created + private SceneToPhysEngineConnector m_sceneToPhysEngineConnector = null; //list of idle physics engines that have registered. private List m_idlePhysEngineList = new List(); @@ -88,27 +93,176 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //private int QuarkInfo.SizeX; //private int QuarkInfo.SizeY; + #region ICommandableModule Members + private readonly Commander m_commander = new Commander("phys"); + public ICommander CommandInterface + { + get { return m_commander; } + } + + private void InstallInterfaces() + { + // Command cmdSyncStart = new Command("start", CommandIntentions.COMMAND_HAZARDOUS, SyncStart, "Begins synchronization with RegionSyncServer."); + //cmdSyncStart.AddArgument("server_port", "The port of the server to synchronize with", "Integer"); + + // Command cmdSyncStop = new Command("stop", CommandIntentions.COMMAND_HAZARDOUS, SyncStop, "Stops synchronization with RegionSyncServer."); + //cmdSyncStop.AddArgument("server_address", "The IP address of the server to synchronize with", "String"); + //cmdSyncStop.AddArgument("server_port", "The port of the server to synchronize with", "Integer"); + + Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status."); + + //The following two commands are more for easier debugging purpose + // Command cmdSyncSetQuarks = new Command("quarkSpace", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkList, "Set the set of quarks to subscribe to. For debugging purpose. Should be issued before \"sync start\""); + // cmdSyncSetQuarks.AddArgument("quarkSpace", "The (rectangle) space of quarks to subscribe, represented by x0_y0,x1_y1, the left-bottom and top-right corners of the rectangel space", "String"); + + // Command cmdSyncSetQuarkSize = new Command("quarksize", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkSize, "Set the size of each quark. For debugging purpose. Should be issued before \"sync quarks\""); + // cmdSyncSetQuarkSize.AddArgument("quarksizeX", "The size on x axis of each quark", "Integer"); + // cmdSyncSetQuarkSize.AddArgument("quarksizeY", "The size on y axis of each quark", "Integer"); + + // m_commander.RegisterCommand("start", cmdSyncStart); + // m_commander.RegisterCommand("stop", cmdSyncStop); + m_commander.RegisterCommand("status", cmdSyncStatus); + // m_commander.RegisterCommand("quarkSpace", cmdSyncSetQuarks); + + lock (m_scene) + { + // Add this to our scene so scripts can call these functions + m_scene.RegisterModuleCommander(m_commander); + } + } + + /// + /// Processes commandline input. Do not call directly. + /// + /// Commandline arguments + private void EventManager_OnPluginConsole(string[] args) + { + if (args[0] == "phys") + { + if (args.Length == 1) + { + m_commander.ProcessConsoleCommand("help", new string[0]); + return; + } + + string[] tmpArgs = new string[args.Length - 2]; + int i; + for (i = 2; i < args.Length; i++) + tmpArgs[i - 2] = args[i]; + + m_commander.ProcessConsoleCommand(args[1], tmpArgs); + } + } + + private void SyncStart(Object[] args) + { + return; + } + private void SyncStop(Object[] args) + { + return; + } + private void SyncStatus(Object[] args) + { + lock (m_physEngineConnector_lock) + { + if (m_physEngineConnectors.Count == 0) + { + m_log.Warn(LogHeader + " Not currently synchronized"); + return; + } + m_log.Warn(LogHeader + " Synchronized"); + foreach (SceneToPhysEngineConnector pec in m_physEngineConnectors) + { + m_log.Warn(pec.GetStats()); + } + } + } + + #endregion + // Check if any of the client views are in a connected state public bool Synced { - get - { - return (m_physEngineConnectors.Count > 0); - } + get { return (m_physEngineConnectors.Count > 0); } } public static bool IsPhysEngineScene { - get { return (m_syncServerInitialized != 0); } + get { return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0); } + } + public static bool IsPhysEngineScene2() + { + return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0); } public static bool IsActivePhysEngineScene { - get { return (m_syncServerInitialized != 0 && m_totalConnections != 0); } + get { + System.Console.WriteLine("IsActivePhysEngineScene: si={0} tc={1}", + SceneToPhysEngineSyncServer.m_syncServerInitialized, + SceneToPhysEngineSyncServer.m_totalConnections); + return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0 + && SceneToPhysEngineSyncServer.m_totalConnections > 0); + } + } + public static bool IsActivePhysEngineScene2() + { + return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0 + && SceneToPhysEngineSyncServer.m_totalConnections > 0); } public static bool IsPhysEngineActor { get { return PhysEngineToSceneConnectorModule.IsPhysEngineActor; } } + /// + /// The scene is unknown by ODE so we have to look through the scenes to + /// find the one with this PhysicsActor so we can send the update. + /// + /// + public static void RouteUpdate(PhysicsActor pa) + { + SceneObjectPart sop = null; + Scene s = null; + foreach (Scene ss in m_allScenes) + { + try + { + sop = ss.GetSceneObjectPart(pa.LocalID); + } + catch + { + sop = null; + } + if (sop != null) + { + s = ss; + break; + } + } + if (s != null) + { + if (s.SceneToPhysEngineSyncServer != null) + { + s.SceneToPhysEngineSyncServer.SendUpdate(pa); + } + else + { + Console.WriteLine("RouteUpdate: SceneToPhysEngineSyncServer is no available"); + } + } + else + { + Console.WriteLine("RouteUpdate: no SOP for update"); + } + return; + } + + public void SendUpdate(PhysicsActor pa) + { + // m_log.DebugFormat("{0}: SendUpdate for {1}", LogHeader, pa.LocalID); + this.m_sceneToPhysEngineConnector.SendPhysUpdateAttributes(pa); + } + #endregion // Constructor @@ -126,8 +280,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_addr = IPAddress.Parse(addr); m_port = port; + m_scene.RegisterModuleInterface(this); + + // remember all the scenes that are configured for connection to physics engine + if (!m_allScenes.Contains(m_scene)) + { + m_allScenes.Add(m_scene); + } + InitQuarksInScene(); SubscribeToEvents(); + m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; + InstallInterfaces(); } @@ -142,12 +306,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Start the server public void Start() { + SceneToPhysEngineSyncServer.m_syncServerInitialized++; m_listenerThread = new Thread(new ThreadStart(Listen)); m_listenerThread.Name = "SceneToPhysEngineSyncServer Listener"; - m_log.WarnFormat(LogHeader + ": Starting {0} thread", m_listenerThread.Name); + m_log.DebugFormat("{0}: Starting {1} thread", LogHeader, m_listenerThread.Name); m_listenerThread.Start(); - //m_log.Warn("[REGION SYNC SERVER] Started"); - m_syncServerInitialized++; + // m_log.DebugFormat("{0}: Started", LogHeader); } @@ -155,7 +319,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Stop the server and disconnect all RegionSyncClients public void Shutdown() { - m_syncServerInitialized--; + m_log.DebugFormat("{0}: Shutdown", LogHeader); + SceneToPhysEngineSyncServer.m_syncServerInitialized--; // Stop the listener and listening thread so no new clients are accepted m_listener.Stop(); m_listenerThread.Abort(); @@ -197,12 +362,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { lock (m_physEngineConnector_lock) { - //Dictionary currentlist = m_physEngineConnectors; - //Dictionary newlist = new Dictionary(currentlist); m_physEngineConnectors.Add(peConnector); - // Threads holding the previous version of the list can keep using it since - // they will not hold it for long and get a new copy next time they need to iterate - //m_physEngineConnectors = newlist; + m_sceneToPhysEngineConnector = peConnector; } } @@ -237,6 +398,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule TcpClient tcpclient = m_listener.AcceptTcpClient(); IPAddress addr = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Address; int port = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Port; + SceneToPhysEngineSyncServer.m_totalConnections++; + // m_log.DebugFormat("{0}: m_totalConnections = {1}", LogHeader, SceneToPhysEngineSyncServer.m_totalConnections); ActorStatus actorStatus = GetActorStatus(tcpclient); @@ -249,10 +412,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule break; case ActorStatus.Idle: IdlePhysEngineInfo idleSE = new IdlePhysEngineInfo(tcpclient); - m_log.Debug(": adding an idle SE ("+addr+","+port+")"); + m_log.DebugFormat("{0}: adding an idle SE ({1}:{2})", LogHeader, addr, port); m_idlePhysEngineList.Add(idleSE); break; default: + m_log.DebugFormat("{0}: Unknown actor status", LogHeader); break; } @@ -260,7 +424,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } catch (SocketException e) { - m_log.WarnFormat(LogHeader + " [Listen] SocketException: {0}", e); + m_log.WarnFormat("{0}: [Listen] SocketException: {1}", LogHeader, e); } } diff --git a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs index 3d30a45f3e..9757695277 100755 --- a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs @@ -30,6 +30,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Framework.Interfaces { @@ -40,5 +41,6 @@ namespace OpenSim.Region.Framework.Interfaces // static bool IsActivePhysEngineScene { get; } // static bool IsPhysEngineActor { get; } bool DebugWithViewer { get; } + void SendUpdate(PhysicsActor pa); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs index 1526c00a0d..c5eeba70b4 100755 --- a/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs @@ -30,6 +30,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Framework.Interfaces { @@ -39,5 +40,6 @@ namespace OpenSim.Region.Framework.Interfaces // static bool IsPhysEngineScene { get; } // static bool IsActivePhysEngineScene { get; } // static bool IsPhysEngineActor { get; } + void SendUpdate(PhysicsActor pa); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7a0d6c52e6..69bf1ca305 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -415,28 +415,18 @@ namespace OpenSim.Region.Framework.Scenes protected ISceneToPhysEngineServer m_sceneToPhysEngineSyncServer = null; public ISceneToPhysEngineServer SceneToPhysEngineSyncServer { - get { return m_sceneToPhysEngineSyncServer; } + get + { + if (m_sceneToPhysEngineSyncServer == null) + { + // kludge since this module is loaded in postInitialize + m_sceneToPhysEngineSyncServer = RequestModuleInterface(); + } + return m_sceneToPhysEngineSyncServer; + } set { m_sceneToPhysEngineSyncServer = value; } } - // list of physactors for this scene so we can find them later for remote physics - public Dictionary PhysActors = new Dictionary(); - public void AddPhysActor(uint id, PhysicsActor pActor) - { - if (PhysActors.ContainsKey(id)) { - PhysActors.Remove(id); - } - PhysActors.Add(id, pActor); - return; - } - public void RemovePhysActor(uint id) - { - if (PhysActors.ContainsKey(id)) { - PhysActors.Remove(id); - } - return; - } - /////////////////////////////////////////////////////////////////////////////////////////////// //This function should only be called by an actor who's local Scene is just a cache of the authorative Scene. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 376019f549..15f2097a21 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -997,7 +997,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.PhysActor != null) { - Scene.RemovePhysActor(m_rootPart.PhysActor.LocalID); m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); m_rootPart.PhysActor = null; } @@ -2275,7 +2274,6 @@ namespace OpenSim.Region.Framework.Scenes //if (linkPart.PhysActor != null) //{ - // m_scene.RemovePhysActor(linkPart.PhysActor.LocalID); // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); //linkPart.PhysActor = null; @@ -2390,7 +2388,6 @@ namespace OpenSim.Region.Framework.Scenes if (linkPart.PhysActor != null) { - m_scene.RemovePhysActor(linkPart.PhysActor.LocalID); m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 46ac996a96..a8de2da8e9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1492,8 +1492,6 @@ 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.LocalID = LocalId; - // RA: register PhysActor with the scene - ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); DoPhysicsPropertyUpdate(RigidBody, true); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } @@ -1756,7 +1754,6 @@ namespace OpenSim.Region.Framework.Scenes // If we're not what we're supposed to be in the physics scene, recreate ourselves. - //ParentGroup.Scene.RemovePhysActor(PhysActor.LocalID); //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public //PhysActor = null; @@ -4286,7 +4283,6 @@ namespace OpenSim.Region.Framework.Scenes AddFlag(PrimFlags.Phantom); if (PhysActor != null) { - ParentGroup.Scene.RemovePhysActor(PhysActor.LocalID); m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public PhysActor = null; @@ -4312,8 +4308,6 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { pa.LocalID = LocalId; - // RA: register PhysActor with scene - ParentGroup.Scene.AddPhysActor(LocalId, PhysActor); DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 8fbc8cd9f2..3e1ef943a6 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -115,6 +115,39 @@ namespace OpenSim.Region.Physics.Manager } } + /// + /// Structure to hold previous values of the PhysicsActor. This is used to see + /// if the values changed before sending updates to the Physics Engine. + /// + public struct PhysActorLastValues + { + public uint localID; + public Vector3 size; + public Vector3 position; + public Vector3 force; + public Vector3 velocity; + public Vector3 torque; + public Quaternion orientation; + public Boolean isPhysical; + public Boolean flying; + public double buoyancy; + public bool Changed(PhysicsActor pa) + { + bool ret = false; + if (localID != pa.LocalID) { localID = pa.LocalID; ret = true; } + if (size != pa.Size) { size = pa.Size; ret = true; } + if (position != pa.Position) { position = pa.Position; ret = true; } + if (force != pa.Force) { force = pa.Force; ret = true; } + if (velocity != pa.Velocity) { velocity = pa.Velocity; ret = true; } + if (torque != pa.Torque) { torque = pa.Torque; ret = true; } + if (orientation != pa.Orientation) { orientation = pa.Orientation; ret = true; } + if (isPhysical != pa.IsPhysical) { isPhysical = pa.IsPhysical; ret = true; } + if (flying != pa.Flying) { flying = pa.Flying; ret = true; } + if (buoyancy != pa.Buoyancy) { buoyancy = pa.Buoyancy; ret = true; } + return ret; + } + } + public abstract class PhysicsActor { public delegate void RequestTerseUpdate(); @@ -144,6 +177,7 @@ namespace OpenSim.Region.Physics.Manager // RA: used to be abstract but changed to allow 'get' without changing all the phys engines public virtual uint LocalID { set { return; } get { return 0; } } + public PhysActorLastValues lastValues; public abstract bool Grabbed { set; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index fc3778cb78..a4222fe599 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -32,6 +32,7 @@ using OpenMetaverse; using Ode.NET; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; +using OpenSim.Region.CoreModules.RegionSync.RegionSyncModule; using log4net; namespace OpenSim.Region.Physics.OdePlugin @@ -202,6 +203,19 @@ namespace OpenSim.Region.Physics.OdePlugin m_name = avName; } + public override void RequestPhysicsterseUpdate() + { + if (PhysEngineToSceneConnectorModule.IsPhysEngineActor) + { + m_log.DebugFormat("[ODE CHARACTER]: Sending terse update for {0}", LocalID); + PhysEngineToSceneConnectorModule.RouteUpdate(this); + } + else + { + base.RequestPhysicsterseUpdate(); + } + } + public override int PhysicsActorType { get { return (int) ActorTypes.Agent; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 3cf45019e7..b44418f8e1 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -47,7 +47,9 @@ using log4net; using OpenMetaverse; using Ode.NET; using OpenSim.Framework; +using OpenSim.Region.Framework; using OpenSim.Region.Physics.Manager; +using OpenSim.Region.CoreModules.RegionSync.RegionSyncModule; namespace OpenSim.Region.Physics.OdePlugin { @@ -252,6 +254,18 @@ namespace OpenSim.Region.Physics.OdePlugin // don't do .add() here; old geoms get recycled with the same hash } + public override void RequestPhysicsterseUpdate() + { + if (PhysEngineToSceneConnectorModule.IsPhysEngineActor) + { + PhysEngineToSceneConnectorModule.RouteUpdate(this); + } + else + { + base.RequestPhysicsterseUpdate(); + } + } + public override int PhysicsActorType { get { return (int) ActorTypes.Prim; } @@ -2641,7 +2655,7 @@ Console.WriteLine(" JointCreateFixed"); _position = l_position; //_parent_scene.remActivePrim(this); if (_parent == null) - base.RequestPhysicsterseUpdate(); + RequestPhysicsterseUpdate(); return; } else @@ -2676,7 +2690,7 @@ Console.WriteLine(" JointCreateFixed"); m_rotationalVelocity.Z = 0; if (_parent == null) - base.RequestPhysicsterseUpdate(); + RequestPhysicsterseUpdate(); m_throttleUpdates = false; throttleCounter = 0; @@ -2729,7 +2743,7 @@ Console.WriteLine(" JointCreateFixed"); if (_parent == null) { - base.RequestPhysicsterseUpdate(); + RequestPhysicsterseUpdate(); } m_lastUpdateSent = true; @@ -2741,7 +2755,7 @@ Console.WriteLine(" JointCreateFixed"); { if (_parent == null) { - base.RequestPhysicsterseUpdate(); + RequestPhysicsterseUpdate(); } } @@ -2776,7 +2790,7 @@ Console.WriteLine(" JointCreateFixed"); { if (_parent == null) { - base.RequestPhysicsterseUpdate(); + RequestPhysicsterseUpdate(); } } else diff --git a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs index 05ce620d0d..3554e43861 100755 --- a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs +++ b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs @@ -77,6 +77,8 @@ public class PECharacter : PhysicsActor float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) { + _position = pos; + _size = size; return; } @@ -100,7 +102,7 @@ public class PECharacter : PhysicsActor set { _localID = value; m_log.Debug("[RPE] PEChar set LocalID"); Prop.Set(_localID, PropType.LocalID, _localID); - } + } get { return _localID; } } public override bool Grabbed { @@ -123,7 +125,7 @@ public class PECharacter : PhysicsActor public override Vector3 Position { get { return _position; } set { _position = value; - // m_log.Debug("[RPE] PEChar set Position"); + // m_log.DebugFormat("[RPE] PEChar set Position: {0}", _position); Prop.Set(_localID, PropType.Position, _position); } } @@ -155,6 +157,7 @@ public class PECharacter : PhysicsActor public override Vector3 Velocity { get { return _velocity; } set { _velocity = value; + m_log.Debug("[RPE] PEChar set Velocity"); Prop.Set(_localID, PropType.Velocity, _velocity); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index e41f15a4e2..0402602673 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -78,6 +78,9 @@ public sealed class PEPrim : PhysicsActor public PEPrim(String primName, PEScene parent_scene, Vector3 pos, Vector3 size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) { + _position = pos; + _size = size; + _orientation = rotation; // SendCreatePrim(primName, parent_scene, pos, size, rotation, mesh, pbs, pisPhysical, dode); } diff --git a/OpenSim/Region/Physics/PEPlugin/PEScene.cs b/OpenSim/Region/Physics/PEPlugin/PEScene.cs index 8df6b2e24c..6d176b7f50 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEScene.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEScene.cs @@ -30,6 +30,8 @@ using log4net; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; using OpenMetaverse; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules.RegionSync.RegionSyncModule; namespace OpenSim.Region.Physics.PEPlugin { @@ -98,6 +100,29 @@ public class PEScene : PhysicsScene public override float Simulate(float timeStep) { + // if we are a physics engine server, send update information + if (SceneToPhysEngineSyncServer.IsPhysEngineScene2()) + { + if (SceneToPhysEngineSyncServer.IsActivePhysEngineScene2()) + { + // m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); + foreach (PEPrim prim in m_prims) + { + if (prim.lastValues.Changed(prim)) + { + SceneToPhysEngineSyncServer.RouteUpdate(prim); + } + } + foreach (PECharacter actor in m_avatars) + { + m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); + SceneToPhysEngineSyncServer.RouteUpdate(actor); + } + } + return 60f; + } + /* + // code borrowed from BasicPhysics to do just avatar movement foreach (PECharacter actor in m_avatars) { Vector3 actorPosition = actor.Position; @@ -146,6 +171,7 @@ public class PEScene : PhysicsScene actor.Position = actorPosition; actor.Velocity = actorVelocity; } + */ return 60f; // returns frames per second } diff --git a/bin/OpenSim.32BitLaunch.pdb b/bin/OpenSim.32BitLaunch.pdb index c89ba323da3be8eded4cdaea190f035f906cf087..5083dd5df55f3252aafaf38f604cb826b7012cc0 100644 GIT binary patch delta 536 zcmZq3X^5Gi!7I+dz)%9jARxL~k?k}iB$I`aq_I*(a5djG~HQmf1B_NZjiYk0Fq+_ntz>f z5f9TO4iAA`wOy#pM#l||lR5YlHXF#_V4NhxA=UuW=4=(?Uyzy? zoS7R_QdF9kZ8ljzRbMdKDkdK&T8t2lRWlNF0IGKcX#xU}buOJJ8mu%S;xs(v{^y!Gc#ucP=p~!lA&R< zjM5uM0g%aD3=AFI4C=>t7~XPEmQe8$<77AiQUwG7KzWc70i#3GlPgr*7;`7@S8?IP z^u%NbRb?IyV0gm7M8}E1fRw})kU5iOwT$^Nyltgw1-6%gK@do@0Wr{V46INwP+Tbi oG5bbGXGTe0AWH&>j{va+5a)v&3It0wOKLo4WE9!VsP~^401f?vOaK4? delta 884 zcmb7?&ubGw6vt<>n`E=5vYRF`X|>k6si7#T^`JIFvM5DDp+OKtVoKabD2=w796afQ z1%)EIyPyXznu{Q`5cUsH6hfg_LA(|rcvA3MS-&q3mE_b1A7=K=oA=|pW0uU?^YqXt zV{9Fe9deHacDV3*uj6vxZ!RQwqPwvJQ8~;!PehDhx?I}j_QA_)Wb^yeH$Uw6$G762 zznUN4`JJojqdeHsAJcKH|5(Cpu@~})H^V-wC^?cce(I!;u{@YZga=DwjZ-ZU01*%Z z|1$Vn`Ubb7QfTpZyP=kMxag?SY>Fd@EDtEj=GtSE5s$X4L4a4wW<7vbur-F*XFE(>}+e< zp@9jUTuKWoT`@^e&$D#v2FYiFPv9INKNi*mCLoolfu8JtC5P{3ZPi#|nfg5=b8ER) zt!D-$nw(9IA(Bi5^y4N#5XgWslZh?;5>F0emjJz9R%t9)(@my3+?K^;w)1M9?leX= zN>{Fb(cczcZpuM}uQ*30&-6`P-cRicb$0;_)P~Olq=V*Ttp8b(UOl7NMKi>}|4+0# WY44Fg3DNk^fsh@&XRQ>=3OT}CO diff --git a/prebuild.xml b/prebuild.xml index 2278e76ff9..70c830dc01 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -534,6 +534,7 @@ + @@ -565,6 +566,7 @@ + @@ -3180,6 +3182,8 @@ + + From 7c6bca16682136de095e32dec0060564a856437f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 14 Dec 2010 15:31:00 -0800 Subject: [PATCH 06/15] physics messages sync'ing both ways. Value change not happening --- .../PhysEngineToSceneConnector.cs | 48 +++++++++++++----- .../PhysEngineToSceneConnectorModule.cs | 27 +++++++--- .../RegionSyncModule/RegionSyncClient.cs | 8 +++ .../RegionSyncModule/RegionSyncClientView.cs | 1 + .../RegionSyncServerModule.cs | 1 + .../SceneToPhysEngineConnector.cs | 42 ++++++++++----- .../SceneToPhysEngineSyncServer.cs | 27 +++++++--- .../IPhysEngineToSceneConnectorModule.cs | 6 +-- .../Interfaces/ISceneToPhysEngineServer.cs | 6 +-- OpenSim/Region/Framework/Scenes/Scene.cs | 20 ++++++-- .../Region/Physics/Manager/PhysicsActor.cs | 7 ++- .../Region/Physics/OdePlugin/ODECharacter.cs | 13 +++-- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 16 +++--- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 4 +- OpenSim/Region/Physics/PEPlugin/PEScene.cs | 11 ++-- bin/OpenSim.32BitLaunch.exe | Bin 5632 -> 5632 bytes bin/OpenSim.32BitLaunch.pdb | Bin 11776 -> 0 bytes 17 files changed, 171 insertions(+), 66 deletions(-) delete mode 100644 bin/OpenSim.32BitLaunch.pdb diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 8631af58f5..7e1d4d00dd 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -375,20 +375,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { uint localID = data["localID"].AsUInteger(); // m_log.DebugFormat("{0}: HandlPhysUpdateAttributes for {1}", LogHeader, localID); - SceneObjectPart sop = m_validLocalScene.GetSceneObjectPart(localID); - if (sop != null) + PhysicsActor pa = FindPhysicsActor(localID); + if (pa != null) { - sop.PhysActor.Size = data["size"].AsVector3(); - sop.PhysActor.Position = data["position"].AsVector3(); - sop.PhysActor.Force = data["force"].AsVector3(); - sop.PhysActor.Velocity = data["velocity"].AsVector3(); - sop.PhysActor.Torque = data["torque"].AsVector3(); - sop.PhysActor.Orientation = data["orientantion"].AsQuaternion(); - sop.PhysActor.IsPhysical = data["isPhysical"].AsBoolean(); // receive?? - sop.PhysActor.Flying = data["flying"].AsBoolean(); // receive?? - sop.PhysActor.Kinematic = data["kinematic"].AsBoolean(); // receive?? - sop.PhysActor.Buoyancy = (float)(data["buoyancy"].AsReal()); - sop.PhysActor.Shape = sop.Shape; + pa.Size = data["size"].AsVector3(); + pa.Position = data["position"].AsVector3(); + pa.Force = data["force"].AsVector3(); + pa.Velocity = data["velocity"].AsVector3(); + pa.Torque = data["torque"].AsVector3(); + pa.Orientation = data["orientantion"].AsQuaternion(); + pa.IsPhysical = data["isPhysical"].AsBoolean(); // receive?? + pa.Flying = data["flying"].AsBoolean(); // receive?? + pa.Kinematic = data["kinematic"].AsBoolean(); // receive?? + pa.Buoyancy = (float)(data["buoyancy"].AsReal()); + SceneObjectPart sop = m_validLocalScene.GetSceneObjectPart(localID); + if (sop != null) + { + pa.Shape = sop.Shape; + } } else { @@ -404,9 +408,25 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } + // Find the physics actor whether it is an object or a scene presence + private PhysicsActor FindPhysicsActor(uint localID) + { + SceneObjectPart sop = m_validLocalScene.GetSceneObjectPart(localID); + if (sop != null) + { + return sop.PhysActor; + } + ScenePresence sp = m_validLocalScene.GetScenePresence(localID); + if (sp != null) + { + return sp.PhysicsActor; + } + return null; + } + public void SendPhysUpdateAttributes(PhysicsActor pa) { - m_log.DebugFormat("{0}: SendPhysUpdateAttributes for {1}", LogHeader, pa.LocalID); + // m_log.DebugFormat("{0}: SendPhysUpdateAttributes for {1}", LogHeader, pa.LocalID); OSDMap data = new OSDMap(9); data["localID"] = OSD.FromUInteger(pa.LocalID); data["size"] = OSD.FromVector3(pa.Size); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index 2359fdfb6b..498a810934 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -133,6 +133,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; InstallInterfaces(); + SyncStart(null); // fake a 'phys start' to get things going + m_log.Warn(LogHeader + " Initialised"); // collect all the scenes for later routing @@ -198,15 +200,28 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } - public static bool IsPhysEngineScene + bool IPhysEngineToSceneConnectorModule.IsPhysEngineActor() { - get { return SceneToPhysEngineSyncServer.IsPhysEngineScene; } + return PhysEngineToSceneConnectorModule.IsPhysEngineActorS; } - public static bool IsActivePhysEngineScene + bool IPhysEngineToSceneConnectorModule.IsPhysEngineScene() { - get { return SceneToPhysEngineSyncServer.IsActivePhysEngineScene; } + return PhysEngineToSceneConnectorModule.IsPhysEngineSceneS; } - public static bool IsPhysEngineActor + bool IPhysEngineToSceneConnectorModule.IsActivePhysEngineScene() + { + return PhysEngineToSceneConnectorModule.IsActivePhysEngineSceneS; + } + + public static bool IsPhysEngineSceneS + { + get { return SceneToPhysEngineSyncServer.IsPhysEngineScene2S(); } + } + public static bool IsActivePhysEngineSceneS + { + get { return SceneToPhysEngineSyncServer.IsActivePhysEngineScene2S(); } + } + public static bool IsPhysEngineActorS { get { return (m_activeActors != 0); } } @@ -249,7 +264,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } else { - Console.WriteLine("RouteUpdate: no SOP found"); + Console.WriteLine("RouteUpdate: no SOP found for {0}", pa.LocalID); } return; } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs index d51b6f265e..5688016892 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs @@ -307,6 +307,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); //else //RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); + sog.ScheduleGroupForFullUpdate(); return; } @@ -351,6 +352,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule UUID agentID = data["agentID"].AsUUID(); string first = data["first"].AsString(); string last = data["last"].AsString(); + uint localID = data["localID"].AsUInteger(); Vector3 startPos = data["startPos"].AsVector3(); if (agentID == null || agentID == UUID.Zero || first == null || last == null || startPos == null) { @@ -384,6 +386,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule else { sp.IsSyncedAvatar = true; + m_log.DebugFormat("{0}: Setting avatar local ID to {1}", LogHeader, localID); + sp.LocalId = localID; + if (sp.PhysicsActor != null) + { + sp.PhysicsActor.LocalID = localID; + } } //RegionSyncMessage.HandlerDebug(LogHeader, msg, String.Format("Added new remote avatar \"{0}\" ({1})", first + " " + last, agentID)); RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Added new remote avatar \"{0}\" ({1})", first + " " + last, agentID)); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs index 07aa077dca..fb690e5ef3 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs @@ -331,6 +331,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Let the client managers know about this avatar OSDMap data = new OSDMap(1); data["agentID"] = OSD.FromUUID(presence.ControllingClient.AgentId); + data["localID"] = OSD.FromUInteger(presence.LocalId); data["first"] = OSD.FromString(presence.ControllingClient.FirstName); data["last"] = OSD.FromString(presence.ControllingClient.LastName); data["startPos"] = OSD.FromVector3(presence.ControllingClient.StartPos); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs index ebed0d7bf3..c2268c5d14 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs @@ -701,6 +701,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Let the client managers know that a new agent has connected OSDMap data = new OSDMap(1); data["agentID"] = OSD.FromUUID(client.AgentId); + data["localID"] = OSD.FromUInteger(m_scene.GetScenePresence(client.AgentId).LocalId); data["first"] = OSD.FromString(client.FirstName); data["last"] = OSD.FromString(client.LastName); data["startPos"] = OSD.FromVector3(client.StartPos); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index e2772fe776..22b36462b5 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -318,20 +318,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule try { uint localID = data["localID"].AsUInteger(); - m_log.DebugFormat("{0}: received PhysUpdateAttributes for {1}", LogHeader, localID); - SceneObjectPart sop = m_scene.GetSceneObjectPart(localID); - if (sop != null) + // m_log.DebugFormat("{0}: received PhysUpdateAttributes for {1}", LogHeader, localID); + PhysicsActor pa = FindPhysicsActor(localID); + if (pa != null) { - sop.PhysActor.Size = data["size"].AsVector3(); - sop.PhysActor.Position = data["position"].AsVector3(); - sop.PhysActor.Force = data["force"].AsVector3(); - sop.PhysActor.Velocity = data["velocity"].AsVector3(); - sop.PhysActor.Torque = data["torque"].AsVector3(); - sop.PhysActor.Orientation = data["orientantion"].AsQuaternion(); - sop.PhysActor.IsPhysical = data["isPhysical"].AsBoolean(); // receive?? - sop.PhysActor.Flying = data["flying"].AsBoolean(); // receive?? - sop.PhysActor.Kinematic = data["kinematic"].AsBoolean(); // receive?? - sop.PhysActor.Buoyancy = (float)(data["buoyancy"].AsReal()); + pa.Size = data["size"].AsVector3(); + pa.Position = data["position"].AsVector3(); + pa.Force = data["force"].AsVector3(); + pa.Velocity = data["velocity"].AsVector3(); + pa.Torque = data["torque"].AsVector3(); + pa.Orientation = data["orientantion"].AsQuaternion(); + pa.IsPhysical = data["isPhysical"].AsBoolean(); // receive?? + pa.Flying = data["flying"].AsBoolean(); // receive?? + pa.Kinematic = data["kinematic"].AsBoolean(); // receive?? + pa.Buoyancy = (float)(data["buoyancy"].AsReal()); } else { @@ -347,6 +347,22 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } + // Find the physics actor whether it is an object or a scene presence + private PhysicsActor FindPhysicsActor(uint localID) + { + SceneObjectPart sop = m_scene.GetSceneObjectPart(localID); + if (sop != null) + { + return sop.PhysActor; + } + ScenePresence sp = m_scene.GetScenePresence(localID); + if (sp != null) + { + return sp.PhysicsActor; + } + return null; + } + public void SendPhysUpdateAttributes(PhysicsActor pa) { // m_log.DebugFormat("{0}: sending PhysUpdateAttributes for {1}", LogHeader, pa.LocalID); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index 4dc0cc5ed0..7e18befae6 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -182,19 +182,23 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule #endregion // Check if any of the client views are in a connected state + public bool IsPhysEngineScene() { return SceneToPhysEngineSyncServer.IsPhysEngineScene2S(); } + public bool IsActivePhysEngineScene() { return SceneToPhysEngineSyncServer.IsActivePhysEngineScene2S(); } + public bool IsPhysEngineActor() { return SceneToPhysEngineSyncServer.IsPhysEngineActorS; } + public bool Synced { get { return (m_physEngineConnectors.Count > 0); } } - public static bool IsPhysEngineScene + public static bool IsPhysEngineSceneS { get { return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0); } } - public static bool IsPhysEngineScene2() + public static bool IsPhysEngineScene2S() { return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0); } - public static bool IsActivePhysEngineScene + public static bool IsActivePhysEngineSceneS { get { System.Console.WriteLine("IsActivePhysEngineScene: si={0} tc={1}", @@ -204,14 +208,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule && SceneToPhysEngineSyncServer.m_totalConnections > 0); } } - public static bool IsActivePhysEngineScene2() + public static bool IsActivePhysEngineScene2S() { return (SceneToPhysEngineSyncServer.m_syncServerInitialized > 0 && SceneToPhysEngineSyncServer.m_totalConnections > 0); } - public static bool IsPhysEngineActor + public static bool IsPhysEngineActorS { - get { return PhysEngineToSceneConnectorModule.IsPhysEngineActor; } + get { return PhysEngineToSceneConnectorModule.IsPhysEngineActorS; } } /// @@ -238,6 +242,15 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule s = ss; break; } + else + { + ScenePresence sp = ss.GetScenePresence(pa.LocalID); + if (sp != null) + { + s = ss; + break; + } + } } if (s != null) { @@ -252,7 +265,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } else { - Console.WriteLine("RouteUpdate: no SOP for update"); + Console.WriteLine("RouteUpdate: no SOP for update of {0}", pa.LocalID); } return; } diff --git a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs index 9757695277..3a8178acf5 100755 --- a/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IPhysEngineToSceneConnectorModule.cs @@ -37,9 +37,9 @@ namespace OpenSim.Region.Framework.Interfaces //the interface for Scene to sync with Script Engine public interface IPhysEngineToSceneConnectorModule { - // static bool IsPhysEngineScene { get; } - // static bool IsActivePhysEngineScene { get; } - // static bool IsPhysEngineActor { get; } + bool IsPhysEngineScene(); + bool IsActivePhysEngineScene(); + bool IsPhysEngineActor(); bool DebugWithViewer { get; } void SendUpdate(PhysicsActor pa); } diff --git a/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs index c5eeba70b4..7eee23c345 100755 --- a/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneToPhysEngineServer.cs @@ -37,9 +37,9 @@ namespace OpenSim.Region.Framework.Interfaces //the interface for Scene to sync with Script Engine public interface ISceneToPhysEngineServer { - // static bool IsPhysEngineScene { get; } - // static bool IsActivePhysEngineScene { get; } - // static bool IsPhysEngineActor { get; } + bool IsPhysEngineScene(); + bool IsActivePhysEngineScene(); + bool IsPhysEngineActor(); void SendUpdate(PhysicsActor pa); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 69bf1ca305..851cf1ebae 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -427,6 +427,20 @@ namespace OpenSim.Region.Framework.Scenes set { m_sceneToPhysEngineSyncServer = value; } } + // depending on what mode we're in, the different modules are available + protected bool IsPhysEngineActor() + { + if (PhysEngineToSceneConnectorModule != null) + { + return this.PhysEngineToSceneConnectorModule.IsPhysEngineActor(); + } + if (SceneToPhysEngineSyncServer != null) + { + return this.SceneToPhysEngineSyncServer.IsPhysEngineActor(); + } + return false; + } + /////////////////////////////////////////////////////////////////////////////////////////////// //This function should only be called by an actor who's local Scene is just a cache of the authorative Scene. @@ -1670,7 +1684,7 @@ namespace OpenSim.Region.Framework.Scenes int tmpPhysicsMS2 = Util.EnvironmentTickCount(); // Do not simulate physics locally if this is a synced client - if (!IsSyncedClient()) + if (!IsSyncedClient() || this.IsPhysEngineActor()) { if ((m_frame % m_update_physics == 0) && m_physics_enabled) m_sceneGraph.UpdatePreparePhysics(); @@ -1678,7 +1692,7 @@ namespace OpenSim.Region.Framework.Scenes physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); // Do not simulate physics locally if this is a synced client - if (!IsSyncedClient()) + if (!IsSyncedClient() || this.IsPhysEngineActor()) { if (m_frame % m_update_entitymovement == 0) m_sceneGraph.UpdateScenePresenceMovement(); @@ -1686,7 +1700,7 @@ namespace OpenSim.Region.Framework.Scenes int tmpPhysicsMS = Util.EnvironmentTickCount(); // Do not simulate physics locally if this is a synced client - if (!IsSyncedClient()) + if (!IsSyncedClient() || this.IsPhysEngineActor()) { if (m_frame % m_update_physics == 0) { diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 3e1ef943a6..f7c1bf0879 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -121,6 +121,7 @@ namespace OpenSim.Region.Physics.Manager /// public struct PhysActorLastValues { + public uint updateTime; public uint localID; public Vector3 size; public Vector3 position; @@ -176,7 +177,11 @@ namespace OpenSim.Region.Physics.Manager public abstract PrimitiveBaseShape Shape { set; } // RA: used to be abstract but changed to allow 'get' without changing all the phys engines - public virtual uint LocalID { set { return; } get { return 0; } } + uint m_baseLocalID; + public virtual uint LocalID { + set { m_baseLocalID = value; } + get { return m_baseLocalID; } + } public PhysActorLastValues lastValues; public abstract bool Grabbed { set; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index a4222fe599..5ae9f0b76e 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -205,7 +205,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override void RequestPhysicsterseUpdate() { - if (PhysEngineToSceneConnectorModule.IsPhysEngineActor) + if (PhysEngineToSceneConnectorModule.IsPhysEngineActorS) { m_log.DebugFormat("[ODE CHARACTER]: Sending terse update for {0}", LocalID); PhysEngineToSceneConnectorModule.RouteUpdate(this); @@ -234,6 +234,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override uint LocalID { set { m_localID = value; } + get { return m_localID; } } public override bool Grabbed @@ -1153,7 +1154,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (!m_lastUpdateSent) { m_lastUpdateSent = true; - //base.RequestPhysicsterseUpdate(); + // base.RequestPhysicsterseUpdate(); } } @@ -1191,6 +1192,11 @@ namespace OpenSim.Region.Physics.OdePlugin m_hackSentFall = false; } } + if (!m_lastUpdateSent) + { + m_log.DebugFormat("[ODE CHARACTER] UpdatePositionAndVelocity"); + this.RequestPhysicsterseUpdate(); + } } /// @@ -1357,7 +1363,8 @@ namespace OpenSim.Region.Physics.OdePlugin _position.Z = m_taintPosition.Z; } } - + Console.WriteLine("ODECharacter: ProcessTaints: doing update"); + this.RequestPhysicsterseUpdate(); } internal void AddCollisionFrameTime(int p) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index b44418f8e1..87a2589481 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -256,9 +256,10 @@ namespace OpenSim.Region.Physics.OdePlugin public override void RequestPhysicsterseUpdate() { - if (PhysEngineToSceneConnectorModule.IsPhysEngineActor) + if (PhysEngineToSceneConnectorModule.IsPhysEngineActorS) { - PhysEngineToSceneConnectorModule.RouteUpdate(this); + if (this.lastValues.Changed(this)) + PhysEngineToSceneConnectorModule.RouteUpdate(this); } else { @@ -283,6 +284,7 @@ namespace OpenSim.Region.Physics.OdePlugin set { //m_log.Info("[PHYSICS]: Setting TrackerID: " + value); m_localID = value; } + get { return m_localID; } } public override bool Grabbed @@ -2655,7 +2657,7 @@ Console.WriteLine(" JointCreateFixed"); _position = l_position; //_parent_scene.remActivePrim(this); if (_parent == null) - RequestPhysicsterseUpdate(); + this.RequestPhysicsterseUpdate(); return; } else @@ -2690,7 +2692,7 @@ Console.WriteLine(" JointCreateFixed"); m_rotationalVelocity.Z = 0; if (_parent == null) - RequestPhysicsterseUpdate(); + this.RequestPhysicsterseUpdate(); m_throttleUpdates = false; throttleCounter = 0; @@ -2743,7 +2745,7 @@ Console.WriteLine(" JointCreateFixed"); if (_parent == null) { - RequestPhysicsterseUpdate(); + this.RequestPhysicsterseUpdate(); } m_lastUpdateSent = true; @@ -2755,7 +2757,7 @@ Console.WriteLine(" JointCreateFixed"); { if (_parent == null) { - RequestPhysicsterseUpdate(); + this.RequestPhysicsterseUpdate(); } } @@ -2790,7 +2792,7 @@ Console.WriteLine(" JointCreateFixed"); { if (_parent == null) { - RequestPhysicsterseUpdate(); + this.RequestPhysicsterseUpdate(); } } else diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 0402602673..8eb23d6667 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -127,7 +127,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Position { get { return _position; } set { _position = value; - m_log.Debug("[RPE] PEPrim set Position"); + // m_log.Debug("[RPE] PEPrim set Position"); Prop.Set(_localID, PropType.Position, _position); } } @@ -137,7 +137,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Force { get { return _force; } set { _force = value; - m_log.Debug("[RPE] PEPrim set Force"); + // m_log.Debug("[RPE] PEPrim set Force"); Prop.Set(_localID, PropType.Force, _force); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PEScene.cs b/OpenSim/Region/Physics/PEPlugin/PEScene.cs index 6d176b7f50..d5197a0a24 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEScene.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEScene.cs @@ -101,9 +101,9 @@ public class PEScene : PhysicsScene public override float Simulate(float timeStep) { // if we are a physics engine server, send update information - if (SceneToPhysEngineSyncServer.IsPhysEngineScene2()) + if (SceneToPhysEngineSyncServer.IsPhysEngineScene2S()) { - if (SceneToPhysEngineSyncServer.IsActivePhysEngineScene2()) + if (SceneToPhysEngineSyncServer.IsActivePhysEngineScene2S()) { // m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); foreach (PEPrim prim in m_prims) @@ -115,8 +115,11 @@ public class PEScene : PhysicsScene } foreach (PECharacter actor in m_avatars) { - m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); - SceneToPhysEngineSyncServer.RouteUpdate(actor); + // m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); + if (actor.lastValues.Changed(actor)) + { + SceneToPhysEngineSyncServer.RouteUpdate(actor); + } } } return 60f; diff --git a/bin/OpenSim.32BitLaunch.exe b/bin/OpenSim.32BitLaunch.exe index e0c3144fa3fc6c1ac43e4aec76e032b09910ca6d..cc73c8bc981264031193f9d8f48d083ff8801d0d 100755 GIT binary patch delta 418 zcmZqBY0#O_!P22%={d1ShS6{0%5XjgEd~Z}1|V=?V3@%=QBjyDfq{Vs$S=`kV33)t z$fPqll2M&8WO5^roH2PNV>qM1WJV^SG7bg?W}rGo1_rjtjXVaM1DI48nO-n#E@NKB z=$6Ew$DqyN2_%gfGJvEt14zUhOa?PF0NKe5tAJ!S!*(E9%y0lmRx_MraA9C+0GkOk znSo(*8mkzqK;&^RrzKZ@yEO!#_51BUwP^F;g?#fFQzkp|D~mb+-NDFU z0EZ?(-x_Q_%m0~?*@A&%@?k;M$r}U(7#TMI6=Y$WJb@>IQvnjx0alv@Mcy+`G++k+ DUdLIT delta 563 zcmX|8O=uHQ7@TjDv^8C~hDPxxg%&MR4b7HTr4gjHv05t<5}{OzCWe>U~Tp`c4IE_b~=kT6<4WGykzLIa?8xru> zX^IYdr%rfR1G@q{!f!TbKBfz&?)?0-vN8Yqw^|JrBYlG1Mc1|Cv6yA&t4^u1SkAgu zZP=<6)UV+3NuYVprk6%kh;`m*y&FiS6KQwv%0lYm=gAjmAG`{7<|M%HQ}G2Sm#^lt zcImQtY-C)$?LKYb3IH%HsXk}Eza`PI4DuEh%%KfcWVr< z$%WQGNrdS+O--5V1mSphd%lQo0=lw7gF8*ij}oKA2##Q!81tTo{Mxque{XNcy-@gv HG|bMwvv+t> diff --git a/bin/OpenSim.32BitLaunch.pdb b/bin/OpenSim.32BitLaunch.pdb deleted file mode 100644 index 5083dd5df55f3252aafaf38f604cb826b7012cc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11776 zcmeHM?`vCC7=F{%Eoqu=>9o2{C7Yew+Io|=nx<9O+O$Hjq1CLVN+eCQ)P^RxBgxe1 z2k#W-K8WmtARSIn#{~VT=un46N^v3xPWK1+K~!*cBC=1d&vSotL8Ky`lBM@;pFHQB z`<`>peb0N(kM~A1se)Qmr%S%DKit;li^d-Ebt{2@r+&v^OdvJ-zubysiFwE^2HC$= zV1fA+TQ;%sqFM(MZR&-Gbgd1-lx zYrDo~!oBg4!|8l1lZ%%MNAk15)$Bo4%@(bk($zVTDGeu&8(SrJ9A(>NBMUhl* zTt)rjwfd`By}p@4{i#eTYt%n{tv=VBe&9iX!hYHNQ{5E*+0V}J0}c(X4}I74z@_mE zj(@w)qdr1}`dE=E9KU@4+g^F5dkKrb)}P^VdZ`n{0W8AXzQhCZ}O zN2k=)UFiFH@%_gxMLyl*s`=!-4<@M-l|ktQ*P$Zs&3%V4H#qcqzabyu4ImEuS^c^V z`F6AXE=+SwwtzQ-?*=!4_k!;L!)G=6?S60<7+W6g0Jset0k?w>f)(%>*bk0_1K=mX zmzS2c1h@nFNih1WCBbM*%YtDK4Ua1KfnNj%!LNY3!E@jc_!OA!yl(Poa1Y8|u&xIh z9=t&YTEWi(;{ekEpbLk0A~?!xuAz@5@)t;bmB z!z0nQ#8AFeIGPw$Gx?Gfnq-fDoolYc+yFGo{<5+_FhIegSB1hQ(H7eRRciqs)_lI( zWuh_t=yuVpy#ZeWC-k^hZ?N^c>fe8k@zbsj{oG%Vs~MaDYs8}~I99(?P>+5~;d5Hd^P%O*>kWBX@iX(*yoDjWp&?HF z=0@7OS~0xV_dlLl{ll63Y$QLeia(#srHkS(7E=D1bn;NTFqKtPvqr&mCYvt$uS5Kg z!3NrrF#`%W8Z3iv%1r=;^VM#EXLwuIX8{kYGe)uiApRh#?#Lo%kk)_+U?0$e_oyA{ z2RI)v_OcD&*f56T0yst-6DPor#|;46XEcK2$TQ{^z?RCfz|ED@6}u<41#Aoa&ldO- D Date: Wed, 15 Dec 2010 15:05:40 -0800 Subject: [PATCH 07/15] remove debug statements. Pass terrain to physics engine --- .../RegionSyncModule/PhysEngineToSceneConnectorModule.cs | 8 ++++++++ .../RegionSync/RegionSyncModule/RegionSyncClient.cs | 1 + .../RegionSyncModule/SceneToPhysEngineSyncServer.cs | 5 ++++- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 8 +++++--- OpenSim/Region/Physics/PEPlugin/PECharacter.cs | 6 ------ OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 2 +- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index 498a810934..fa85318920 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -250,6 +250,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule s = ss; break; } + { + ScenePresence sp = ss.GetScenePresence(pa.LocalID); + if (sp != null) + { + s = ss; + break; + } + } } if (s != null) { diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs index 5688016892..20131363bf 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs @@ -282,6 +282,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule case RegionSyncMessage.MsgType.Terrain: { m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); + m_scene.PhysicsScene.SetTerrain(m_scene.Heightmap.GetFloatsSerialised()); RegionSyncMessage.HandleSuccess(LogHeader, msg, "Synchronized terrain"); return; } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index 7e18befae6..8d91c50f7e 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -273,7 +273,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void SendUpdate(PhysicsActor pa) { // m_log.DebugFormat("{0}: SendUpdate for {1}", LogHeader, pa.LocalID); - this.m_sceneToPhysEngineConnector.SendPhysUpdateAttributes(pa); + if (pa.lastValues.Changed(pa)) + { + this.m_sceneToPhysEngineConnector.SendPhysUpdateAttributes(pa); + } } #endregion diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 5ae9f0b76e..23249dcf55 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -207,8 +207,11 @@ namespace OpenSim.Region.Physics.OdePlugin { if (PhysEngineToSceneConnectorModule.IsPhysEngineActorS) { - m_log.DebugFormat("[ODE CHARACTER]: Sending terse update for {0}", LocalID); - PhysEngineToSceneConnectorModule.RouteUpdate(this); + // m_log.DebugFormat("[ODE CHARACTER]: Sending terse update for {0}", LocalID); + if (this.lastValues.Changed(this)) + { + PhysEngineToSceneConnectorModule.RouteUpdate(this); + } } else { @@ -1194,7 +1197,6 @@ namespace OpenSim.Region.Physics.OdePlugin } if (!m_lastUpdateSent) { - m_log.DebugFormat("[ODE CHARACTER] UpdatePositionAndVelocity"); this.RequestPhysicsterseUpdate(); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs index 3554e43861..4bdbcce943 100755 --- a/OpenSim/Region/Physics/PEPlugin/PECharacter.cs +++ b/OpenSim/Region/Physics/PEPlugin/PECharacter.cs @@ -88,19 +88,16 @@ public class PECharacter : PhysicsActor public override Vector3 Size { get { return _size; } set { _size = value; - m_log.Debug("[RPE] PEChar set Size"); Prop.Set(_localID, PropType.Size, _size); } } public override PrimitiveBaseShape Shape { set { _pbs = value; - m_log.Debug("[RPE] PEChar set Shape"); Prop.Set(_localID, PropType.Shape, _pbs); } } public override uint LocalID { set { _localID = value; - m_log.Debug("[RPE] PEChar set LocalID"); Prop.Set(_localID, PropType.LocalID, _localID); } get { return _localID; } @@ -125,7 +122,6 @@ public class PECharacter : PhysicsActor public override Vector3 Position { get { return _position; } set { _position = value; - // m_log.DebugFormat("[RPE] PEChar set Position: {0}", _position); Prop.Set(_localID, PropType.Position, _position); } } @@ -135,7 +131,6 @@ public class PECharacter : PhysicsActor public override Vector3 Force { get { return _force; } set { _force = value; - m_log.Debug("[RPE] PEChar set Force"); Prop.Set(_localID, PropType.Force, _force); } } @@ -157,7 +152,6 @@ public class PECharacter : PhysicsActor public override Vector3 Velocity { get { return _velocity; } set { _velocity = value; - m_log.Debug("[RPE] PEChar set Velocity"); Prop.Set(_localID, PropType.Velocity, _velocity); } } diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 8eb23d6667..0a3baa03b0 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -90,7 +90,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Size { get { return _size; } set { _size = value; - m_log.Debug("[RPE] PEPrim set Size"); + // m_log.Debug("[RPE] PEPrim set Size"); Prop.Set(_localID, PropType.Size, _size); } } From e1c36506340a46b110ae0fdacb2e54e1ee494e50 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 20 Dec 2010 14:06:14 -0800 Subject: [PATCH 08/15] Remove chatty debug messages. Damp update value checking. Physics sync message logging. --- .../PhysEngineToSceneConnector.cs | 93 ++++++++++++++++++- .../RegionSyncModule/RegionSyncClient.cs | 6 +- .../RegionSyncModule/RegionSyncClientView.cs | 4 +- .../RegionSyncModule/RegionSyncMessage.cs | 5 + .../SceneToPhysEngineConnector.cs | 1 + .../SceneToPhysEngineSyncServer.cs | 5 +- .../Region/Physics/Manager/PhysicsActor.cs | 15 ++- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 2 +- 8 files changed, 114 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 7e1d4d00dd..1ecf73a9d0 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -108,6 +108,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); m_sysConfig = sysConfig; + logEnabled = m_sysConfig.GetBoolean("LogEnabled", false); + logDir = m_sysConfig.GetString("LogDir", "."); + //assume we are connecting to the whole scene as one big quark m_subscribedQuarks = new QuarkSubsriptionInfo(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); } @@ -255,7 +258,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_client.Client.Close(); m_client.Close(); } - + LogMessageClose(); } // Listen for messages from a RegionSyncServer @@ -298,12 +301,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Send a message to a single connected RegionSyncServer private void Send(string msg) { + LogMessage(logOutput, msg); byte[] bmsg = System.Text.Encoding.ASCII.GetBytes(msg + System.Environment.NewLine); Send(bmsg); } private void Send(RegionSyncMessage msg) { + LogMessage(logOutput, msg); Send(msg.ToBytes()); //m_log.WarnFormat("{0} Sent {1}", LogHeader, msg.ToString()); } @@ -342,6 +347,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { //TO FINISH: + LogMessage(logInput, msg); switch (msg.Type) { case RegionSyncMessage.MsgType.RegionName: @@ -378,7 +384,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule PhysicsActor pa = FindPhysicsActor(localID); if (pa != null) { - pa.Size = data["size"].AsVector3(); + Vector3 sizeTemp = data["size"].AsVector3(); + if (sizeTemp.Z != 0) + { + // pa.Size = sizeTemp; + } pa.Position = data["position"].AsVector3(); pa.Force = data["force"].AsVector3(); pa.Velocity = data["velocity"].AsVector3(); @@ -509,7 +519,84 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } #endregion Handlers for events/updates from Scene + #region Message Logging + private bool logInput = false; + private bool logOutput = true; + private bool logEnabled = true; + private class MsgLogger + { + public DateTime startTime; + public string path = null; + public System.IO.TextWriter Log = null; + } + private MsgLogger logWriter = null; + private TimeSpan logMaxFileTime = new TimeSpan(0, 5, 0); // (h,m,s) => 5 minutes + private string logDir = "/stats/stats"; + private object logLocker = new Object(); + + private void LogMessage(bool direction, RegionSyncMessage rsm) + { + if (!logEnabled) return; // save to work of the ToStringFull if not enabled + LogMessage(direction, rsm.ToStringFull()); + } + + private void LogMessage(bool direction, string msg) + { + if (!logEnabled) return; + + lock (logLocker) + { + try + { + DateTime now = DateTime.Now; + if (logWriter == null || (now > logWriter.startTime + logMaxFileTime)) + { + if (logWriter != null && logWriter.Log != null) + { + logWriter.Log.Close(); + logWriter.Log.Dispose(); + logWriter.Log = null; + } + + // First log file or time has expired, start writing to a new log file + logWriter = new MsgLogger(); + logWriter.startTime = now; + logWriter.path = (logDir.Length > 0 ? logDir + System.IO.Path.DirectorySeparatorChar.ToString() : "") + + String.Format("physics-{0}.log", now.ToString("yyyyMMddHHmmss")); + logWriter.Log = new StreamWriter(File.Open(logWriter.path, FileMode.Append, FileAccess.Write)); + } + if (logWriter != null && logWriter.Log != null) + { + StringBuilder buff = new StringBuilder(); + buff.Append(now.ToString("yyyyMMddHHmmss")); + buff.Append(" "); + buff.Append(direction ? "A->S:" : "S->A:"); + buff.Append(msg); + buff.Append("\r\n"); + logWriter.Log.Write(buff.ToString()); + } + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e); + logEnabled = false; + } + } + return; + } + + private void LogMessageClose() + { + if (logWriter != null && logWriter.Log != null) + { + logWriter.Log.Close(); + logWriter.Log.Dispose(); + logWriter.Log = null; + logWriter = null; + } + logEnabled = false; + } + #endregion Message Logging } - } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs index 20131363bf..854ea197c3 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs @@ -1023,7 +1023,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleGrabObject(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List surfaceArgs) { - m_log.DebugFormat("[REGION SYNC CLIENT] HandleGrabObject for {0}", remoteClient.AgentId.ToString()); + // m_log.DebugFormat("[REGION SYNC CLIENT] HandleGrabObject for {0}", remoteClient.AgentId.ToString()); OSDMap data = new OSDMap(4); data["agentID"] = OSD.FromUUID(remoteClient.AgentId); data["localID"] = OSD.FromUInteger(localID); @@ -1034,7 +1034,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List surfaceArgs) { - m_log.DebugFormat("[REGION SYNC CLIENT] HandleGrabUpdate for {0}", remoteClient.AgentId.ToString()); + // m_log.DebugFormat("[REGION SYNC CLIENT] HandleGrabUpdate for {0}", remoteClient.AgentId.ToString()); OSDMap data = new OSDMap(5); data["agentID"] = OSD.FromUUID(remoteClient.AgentId); data["objectID"] = OSD.FromUUID(objectID); @@ -1046,7 +1046,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleDeGrabObject(uint localID, IClientAPI remoteClient, List surfaceArgs) { - m_log.DebugFormat("[REGION SYNC CLIENT] HandleDeGrabObject for {0}", remoteClient.AgentId.ToString()); + // m_log.DebugFormat("[REGION SYNC CLIENT] HandleDeGrabObject for {0}", remoteClient.AgentId.ToString()); OSDMap data = new OSDMap(3); data["agentID"] = OSD.FromUUID(remoteClient.AgentId); data["localID"] = OSD.FromUInteger(localID); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs index fb690e5ef3..b40d26b7c2 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientView.cs @@ -656,8 +656,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } UUID agentID = data["agentID"].AsUUID(); UUID objectID = data["objectID"].AsUUID(); - m_log.DebugFormat("{0} GrabUpdate for {1}. ObjectID={2}", - LogHeader, agentID.ToString(), objectID.ToString()); + // m_log.DebugFormat("{0} GrabUpdate for {1}. ObjectID={2}", + // LogHeader, agentID.ToString(), objectID.ToString()); Vector3 offset = data["offset"].AsVector3(); Vector3 pos = data["pos"].AsVector3(); OSDArray surfaceArray = (OSDArray)data["surfaceArgs"]; diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs index 0f1324172f..793fc367ab 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncMessage.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using System.IO; using OpenMetaverse; using log4net; @@ -205,6 +206,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { return String.Format("{0} ({1} bytes)", m_type.ToString(), m_data.Length.ToString()); } + public string ToStringFull() + { + return String.Format("{0}:{1})", m_type.ToString(), Encoding.ASCII.GetString(m_data)); + } #endregion public static void HandleSuccess(string header, RegionSyncMessage msg, string message) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index 22b36462b5..b3c62986b5 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -156,6 +156,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //m_scene.EventManager.OnRezScript += SEConnectorOnRezScript; //m_scene.EventManager.OnScriptReset += SEConnectorOnScriptReset; //m_scene.EventManager.OnUpdateScript += SEConnectorOnUpdateScript; + // Create a thread for the receive loop m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); })); m_receive_loop.Name = Description; diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index 8d91c50f7e..7e18befae6 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -273,10 +273,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void SendUpdate(PhysicsActor pa) { // m_log.DebugFormat("{0}: SendUpdate for {1}", LogHeader, pa.LocalID); - if (pa.lastValues.Changed(pa)) - { - this.m_sceneToPhysEngineConnector.SendPhysUpdateAttributes(pa); - } + this.m_sceneToPhysEngineConnector.SendPhysUpdateAttributes(pa); } #endregion diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index f7c1bf0879..9f59844ea3 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -137,16 +137,23 @@ namespace OpenSim.Region.Physics.Manager bool ret = false; if (localID != pa.LocalID) { localID = pa.LocalID; ret = true; } if (size != pa.Size) { size = pa.Size; ret = true; } - if (position != pa.Position) { position = pa.Position; ret = true; } - if (force != pa.Force) { force = pa.Force; ret = true; } - if (velocity != pa.Velocity) { velocity = pa.Velocity; ret = true; } - if (torque != pa.Torque) { torque = pa.Torque; ret = true; } + if (!AlmostEqual(position, pa.Position)) { position = pa.Position; ret = true; } + if (!AlmostEqual(force, pa.Force)) { force = pa.Force; ret = true; } + if (!AlmostEqual(velocity, pa.Velocity)) { velocity = pa.Velocity; ret = true; } + if (!AlmostEqual(torque, pa.Torque)) { torque = pa.Torque; ret = true; } if (orientation != pa.Orientation) { orientation = pa.Orientation; ret = true; } if (isPhysical != pa.IsPhysical) { isPhysical = pa.IsPhysical; ret = true; } if (flying != pa.Flying) { flying = pa.Flying; ret = true; } if (buoyancy != pa.Buoyancy) { buoyancy = pa.Buoyancy; ret = true; } return ret; } + private bool AlmostEqual(Vector3 a, Vector3 b) + { + if (Math.Abs(a.X - b.X) > 0.001) return false; + if (Math.Abs(a.Y - b.Y) > 0.001) return false; + if (Math.Abs(a.Z - b.Z) > 0.001) return false; + return true; + } } public abstract class PhysicsActor diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 0a3baa03b0..4c88485945 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -102,7 +102,7 @@ public sealed class PEPrim : PhysicsActor } public override uint LocalID { set { _localID = value; - m_log.Debug("[RPE] PEPrim set LocalID"); + // m_log.Debug("[RPE] PEPrim set LocalID"); Prop.Set(_localID, PropType.LocalID, _localID); } get { return _localID; } From a2ca47d7eb6891ce862b4cf70b7f5155b5a333d2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 21 Dec 2010 13:19:09 -0800 Subject: [PATCH 09/15] Add parameter and code for AgentID to track bucket changes. Added ground collision so walking now works --- .../RegionSyncModule/PhysEngineToSceneConnector.cs | 11 ++++++----- .../RegionSyncModule/RegionSyncServerModule.cs | 4 ++++ .../RegionSyncModule/SceneToPhysEngineConnector.cs | 7 +++++++ OpenSim/Region/Physics/Manager/PhysicsActor.cs | 2 ++ OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 7 ++++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 10 +++++++++- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 12 ++++++++++++ OpenSim/Region/Physics/PEPlugin/PEScene.cs | 6 ++++-- 8 files changed, 50 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 1ecf73a9d0..05265f8578 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -380,15 +380,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule try { uint localID = data["localID"].AsUInteger(); + string actorID = data["actorID"].AsString(); // m_log.DebugFormat("{0}: HandlPhysUpdateAttributes for {1}", LogHeader, localID); PhysicsActor pa = FindPhysicsActor(localID); if (pa != null) { - Vector3 sizeTemp = data["size"].AsVector3(); - if (sizeTemp.Z != 0) - { - // pa.Size = sizeTemp; - } + // pa.Size = data["size"].AsVector3(); + pa.ChangingActorID = actorID; pa.Position = data["position"].AsVector3(); pa.Force = data["force"].AsVector3(); pa.Velocity = data["velocity"].AsVector3(); @@ -439,6 +437,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // m_log.DebugFormat("{0}: SendPhysUpdateAttributes for {1}", LogHeader, pa.LocalID); OSDMap data = new OSDMap(9); data["localID"] = OSD.FromUInteger(pa.LocalID); + data["actorID"] = OSD.FromString(RegionSyncServerModule.ActorID); data["size"] = OSD.FromVector3(pa.Size); data["position"] = OSD.FromVector3(pa.Position); data["force"] = OSD.FromVector3(pa.Force); @@ -448,6 +447,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule data["isPhysical"] = OSD.FromBoolean(pa.IsPhysical); data["flying"] = OSD.FromBoolean(pa.Flying); data["buoyancy"] = OSD.FromReal(pa.Buoyancy); + data["isColliding"] = OSD.FromBoolean(pa.IsColliding); + data["isCollidingGround"] = OSD.FromBoolean(pa.CollidingGround); RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.PhysUpdateAttributes, OSDParser.SerializeJsonString(data)); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs index c2268c5d14..822511fd33 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs @@ -48,6 +48,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public class RegionSyncServerModule : IRegionModule, IRegionSyncServerModule, ICommandableModule { private static int DefaultPort = 13000; + public static string ActorID = "XX"; #region IRegionModule Members public void Initialise(Scene scene, IConfigSource config) @@ -74,6 +75,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } + // get identifying actor ID whether in client or server mode + ActorID = syncConfig.GetString("ActorID", "ZZ"); + // If syncConfig does not indicate "server", do not start up server mode string mode = syncConfig.GetString("Mode", "server").ToLower(); if(mode != "server") diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index b3c62986b5..01e36f1006 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -319,10 +319,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule try { uint localID = data["localID"].AsUInteger(); + string actorID = data["actorID"].AsString(); // m_log.DebugFormat("{0}: received PhysUpdateAttributes for {1}", LogHeader, localID); PhysicsActor pa = FindPhysicsActor(localID); if (pa != null) { + pa.ChangingActorID = actorID; pa.Size = data["size"].AsVector3(); pa.Position = data["position"].AsVector3(); pa.Force = data["force"].AsVector3(); @@ -333,6 +335,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule pa.Flying = data["flying"].AsBoolean(); // receive?? pa.Kinematic = data["kinematic"].AsBoolean(); // receive?? pa.Buoyancy = (float)(data["buoyancy"].AsReal()); + pa.CollidingGround = data["isCollidingGround"].AsBoolean(); + pa.IsColliding = data["isCollidingGround"].AsBoolean(); } else { @@ -369,6 +373,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // m_log.DebugFormat("{0}: sending PhysUpdateAttributes for {1}", LogHeader, pa.LocalID); OSDMap data = new OSDMap(9); data["localID"] = OSD.FromUInteger(pa.LocalID); + data["actorID"] = OSD.FromString(RegionSyncServerModule.ActorID); data["size"] = OSD.FromVector3(pa.Size); data["position"] = OSD.FromVector3(pa.Position); data["force"] = OSD.FromVector3(pa.Force); @@ -378,6 +383,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule data["isPhysical"] = OSD.FromBoolean(pa.IsPhysical); data["flying"] = OSD.FromBoolean(pa.Flying); data["buoyancy"] = OSD.FromReal(pa.Buoyancy); + // data["isColliding"] = OSD.FromBoolean(pa.IsColliding); + // data["isCollidingGround"] = OSD.FromBoolean(pa.CollidingGround); RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.PhysUpdateAttributes, OSDParser.SerializeJsonString(data)); diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 9f59844ea3..ce4c45a672 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -190,6 +190,8 @@ namespace OpenSim.Region.Physics.Manager get { return m_baseLocalID; } } public PhysActorLastValues lastValues; + // ID of actor which last updated the values. Send if I did the change. + public string ChangingActorID = "YY"; public abstract bool Grabbed { set; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 23249dcf55..cb4e400d6c 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -208,7 +208,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (PhysEngineToSceneConnectorModule.IsPhysEngineActorS) { // m_log.DebugFormat("[ODE CHARACTER]: Sending terse update for {0}", LocalID); - if (this.lastValues.Changed(this)) + // if the values have changed and it was I who changed them, send an update + if (this.lastValues.Changed(this) && ChangingActorID == RegionSyncServerModule.ActorID) { PhysEngineToSceneConnectorModule.RouteUpdate(this); } @@ -426,6 +427,7 @@ namespace OpenSim.Region.Physics.OdePlugin get { return _position; } set { + base.ChangingActorID = RegionSyncServerModule.ActorID; if (Body == IntPtr.Zero || Shell == IntPtr.Zero) { if (value.IsFinite()) @@ -471,6 +473,7 @@ namespace OpenSim.Region.Physics.OdePlugin get { return new Vector3(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); } set { + base.ChangingActorID = RegionSyncServerModule.ActorID; if (value.IsFinite()) { m_pidControllerActive = true; @@ -792,6 +795,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_pidControllerActive = true; _target_velocity = value; + base.ChangingActorID = RegionSyncServerModule.ActorID; } else { @@ -848,6 +852,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (force.IsFinite()) { + base.ChangingActorID = RegionSyncServerModule.ActorID; if (pushforce) { m_pidControllerActive = false; diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 87a2589481..711dcb29ff 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -258,7 +258,8 @@ namespace OpenSim.Region.Physics.OdePlugin { if (PhysEngineToSceneConnectorModule.IsPhysEngineActorS) { - if (this.lastValues.Changed(this)) + // if the values have changed and it was I who changed them, send an update + if (this.lastValues.Changed(this) && ChangingActorID == RegionSyncServerModule.ActorID) PhysEngineToSceneConnectorModule.RouteUpdate(this); } else @@ -2308,6 +2309,7 @@ Console.WriteLine(" JointCreateFixed"); get { return _position; } set { _position = value; + base.ChangingActorID = RegionSyncServerModule.ActorID; //m_log.Info("[PHYSICS]: " + _position.ToString()); } } @@ -2320,6 +2322,7 @@ Console.WriteLine(" JointCreateFixed"); if (value.IsFinite()) { _size = value; + base.ChangingActorID = RegionSyncServerModule.ActorID; } else { @@ -2342,6 +2345,7 @@ Console.WriteLine(" JointCreateFixed"); if (value.IsFinite()) { m_force = value; + base.ChangingActorID = RegionSyncServerModule.ActorID; } else { @@ -2400,6 +2404,7 @@ Console.WriteLine(" JointCreateFixed"); { _pbs = value; m_taintshape = true; + base.ChangingActorID = RegionSyncServerModule.ActorID; } } @@ -2422,6 +2427,7 @@ Console.WriteLine(" JointCreateFixed"); { if (value.IsFinite()) { + base.ChangingActorID = RegionSyncServerModule.ActorID; _velocity = value; m_taintVelocity = value; @@ -2451,6 +2457,7 @@ Console.WriteLine(" JointCreateFixed"); { m_taintTorque = value; _parent_scene.AddPhysicsActorTaint(this); + base.ChangingActorID = RegionSyncServerModule.ActorID; } else { @@ -2479,6 +2486,7 @@ Console.WriteLine(" JointCreateFixed"); if (QuaternionIsFinite(value)) { _orientation = value; + base.ChangingActorID = RegionSyncServerModule.ActorID; } else m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object"); diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 4c88485945..528ef7064c 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -91,18 +91,21 @@ public sealed class PEPrim : PhysicsActor get { return _size; } set { _size = value; // m_log.Debug("[RPE] PEPrim set Size"); + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Size, _size); } } public override PrimitiveBaseShape Shape { set { _pbs = value; m_log.Debug("[RPE] PEPrim set Shape"); + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Shape, _pbs); } } public override uint LocalID { set { _localID = value; // m_log.Debug("[RPE] PEPrim set LocalID"); + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.LocalID, _localID); } get { return _localID; } @@ -127,6 +130,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Position { get { return _position; } set { _position = value; + ChangingActorID = RegionSyncServerModule.ActorID; // m_log.Debug("[RPE] PEPrim set Position"); Prop.Set(_localID, PropType.Position, _position); } @@ -137,6 +141,7 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Force { get { return _force; } set { _force = value; + ChangingActorID = RegionSyncServerModule.ActorID; // m_log.Debug("[RPE] PEPrim set Force"); Prop.Set(_localID, PropType.Force, _force); } @@ -159,18 +164,21 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Velocity { get { return _velocity; } set { _velocity = value; + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Velocity, _velocity); } } public override Vector3 Torque { get { return _torque; } set { _torque = value; + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Torque, _torque); } } public override float CollisionScore { get { return _collisionScore; } set { _collisionScore = value; + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.CollisionScore, _collisionScore); } } @@ -180,22 +188,26 @@ public sealed class PEPrim : PhysicsActor public override Quaternion Orientation { get { return _orientation; } set { _orientation = value; + ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Orientation, _orientation); } } public override int PhysicsActorType { get { return _physicsActorType; } set { _physicsActorType = value; + ChangingActorID = RegionSyncServerModule.ActorID; } } public override bool IsPhysical { get { return _isPhysical; } set { _isPhysical = value; + ChangingActorID = RegionSyncServerModule.ActorID; } } public override bool Flying { get { return _flying; } set { _flying = value; + ChangingActorID = RegionSyncServerModule.ActorID; } } public override bool diff --git a/OpenSim/Region/Physics/PEPlugin/PEScene.cs b/OpenSim/Region/Physics/PEPlugin/PEScene.cs index d5197a0a24..83b8632940 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEScene.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEScene.cs @@ -108,7 +108,8 @@ public class PEScene : PhysicsScene // m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); foreach (PEPrim prim in m_prims) { - if (prim.lastValues.Changed(prim)) + // if the values have changed and it was I who changed them, send an update + if (prim.lastValues.Changed(prim) && prim.ChangingActorID == RegionSyncServerModule.ActorID) { SceneToPhysEngineSyncServer.RouteUpdate(prim); } @@ -116,7 +117,8 @@ public class PEScene : PhysicsScene foreach (PECharacter actor in m_avatars) { // m_log.DebugFormat("[RPE]: Simulate. p={0}, a={1}", m_prims.Count, m_avatars.Count); - if (actor.lastValues.Changed(actor)) + // if the values have changed and it was I who changed them, send an update + if (actor.lastValues.Changed(actor) && actor.ChangingActorID == RegionSyncServerModule.ActorID) { SceneToPhysEngineSyncServer.RouteUpdate(actor); } From bdeeead120ab0135abca9d76580c05ef620bd0fa Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 22 Dec 2010 15:35:26 -0800 Subject: [PATCH 10/15] Add physics actor taint setting after receiveing update values --- .../RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 05265f8578..169e99290d 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -401,6 +401,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { pa.Shape = sop.Shape; } + m_validLocalScene.PhysicsScene.AddPhysicsActorTaint(pa); } else { From 8aded5bdd00c4998f62381663af7f4caddc26748 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 3 Jan 2011 09:13:44 -0800 Subject: [PATCH 11/15] Debug message in ODEPrim on object creation. Less restrictive on changed test when routing updates in ODEScene --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 711dcb29ff..130b02c613 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -252,6 +252,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_taintadd = true; _parent_scene.AddPhysicsActorTaint(this); // don't do .add() here; old geoms get recycled with the same hash + m_log.DebugFormat("[PHYSICS] Created ODEPrim: n={0}, m={1}, pbs={2}, phys={3}", + primName, mesh == null ? "NULL" : "DEFINED", pbs == null ? "NULL" : "DEFINED", pisPhysical); } public override void RequestPhysicsterseUpdate() @@ -259,7 +261,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (PhysEngineToSceneConnectorModule.IsPhysEngineActorS) { // if the values have changed and it was I who changed them, send an update - if (this.lastValues.Changed(this) && ChangingActorID == RegionSyncServerModule.ActorID) + // if (this.lastValues.Changed(this) && ChangingActorID == RegionSyncServerModule.ActorID) + if (this.lastValues.Changed(this)) PhysEngineToSceneConnectorModule.RouteUpdate(this); } else From ae8f8d60a69e636a58a7cce234e481f397e518e0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 3 Jan 2011 12:21:38 -0800 Subject: [PATCH 12/15] remove some load balancing routine invocations to eliminate build breaks. Remove chatty grab debug messages --- .../RegionSync/RegionSyncModule/RegionSyncClient.cs | 12 ++++++------ .../RegionSyncModule/SceneToPhysEngineConnector.cs | 7 ++++++- .../RegionSyncModule/SceneToPhysEngineSyncServer.cs | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs index 46546c5615..21224dc034 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClient.cs @@ -396,7 +396,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule else { sp.IsSyncedAvatar = true; - m_log.DebugFormat("{0}: Setting avatar local ID to {1}", LogHeader, localID); + m_log.DebugFormat("{0}: Setting avatar local ID to {1}", LogHeader(), localID); sp.LocalId = localID; if (sp.PhysicsActor != null) { @@ -978,7 +978,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleAgentRequestSit(object sender, UUID agentID, UUID targetID, Vector3 offset) { - m_log.DebugFormat("{0} HandleAgentRequestSit for {1}", LogHeader(), agentID.ToString()); + // m_log.DebugFormat("{0} HandleAgentRequestSit for {1}", LogHeader(), agentID.ToString()); OSDMap data = new OSDMap(3); data["agentID"] = OSD.FromUUID(agentID); data["targetID"] = OSD.FromUUID(targetID); @@ -988,7 +988,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) { - m_log.DebugFormat("{0} HandleAgentSit for {1}", LogHeader(), agentID.ToString()); + // m_log.DebugFormat("{0} HandleAgentSit for {1}", LogHeader(), agentID.ToString()); OSDMap data = new OSDMap(1); data["agentID"] = OSD.FromUUID(agentID); Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentSit, OSDParser.SerializeJsonString(data))); @@ -996,7 +996,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleGrabObject(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List surfaceArgs) { - m_log.DebugFormat("{0} HandleGrabObject for {1}", LogHeader(), remoteClient.AgentId.ToString()); + // m_log.DebugFormat("{0} HandleGrabObject for {1}", LogHeader(), remoteClient.AgentId.ToString()); OSDMap data = new OSDMap(4); data["agentID"] = OSD.FromUUID(remoteClient.AgentId); data["localID"] = OSD.FromUInteger(localID); @@ -1007,7 +1007,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List surfaceArgs) { - m_log.DebugFormat("{0} HandleGrabUpdate for {1}", LogHeader(), remoteClient.AgentId.ToString()); + // m_log.DebugFormat("{0} HandleGrabUpdate for {1}", LogHeader(), remoteClient.AgentId.ToString()); OSDMap data = new OSDMap(5); data["agentID"] = OSD.FromUUID(remoteClient.AgentId); data["objectID"] = OSD.FromUUID(objectID); @@ -1019,7 +1019,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule public void HandleDeGrabObject(uint localID, IClientAPI remoteClient, List surfaceArgs) { - m_log.DebugFormat("{0} HandleDeGrabObject for {1}", LogHeader(), remoteClient.AgentId.ToString()); + // m_log.DebugFormat("{0} HandleDeGrabObject for {1}", LogHeader(), remoteClient.AgentId.ToString()); OSDMap data = new OSDMap(3); data["agentID"] = OSD.FromUUID(remoteClient.AgentId); data["localID"] = OSD.FromUInteger(localID); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index 01e36f1006..4df6fa5afd 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -239,6 +239,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule Shutdown(); } return; + /* case RegionSyncMessage.MsgType.LoadBalanceRequest: { m_syncServer.HandleLoadBalanceRequest(this); @@ -260,6 +261,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } return; } + */ case RegionSyncMessage.MsgType.PhysTerseUpdate: { @@ -487,7 +489,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule #endregion Send/Receive messages to/from the remote Physics Engine #region Spacial query functions (should be eventually implemented within Scene) - + /* //This should be a function of Scene, but since we don't have the quark concept in Scene yet, //for now we implement it here. //Ideally, for quark based space representation, the Scene has a list of quarks, and each quark points @@ -512,15 +514,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return sogList; } + */ #endregion #region Load balancing functions + /* public void SendLoadBalanceRejection(string response) { RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.LoadBalanceRejection, response); Send(msg); } + */ #endregion } } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index 7e18befae6..8b432030d0 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -545,6 +545,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule #endregion Event Handlers #region Load balancing members and functions + /* //keep track of idle physics engines that are in the process of load balancing (they are off the idle list, but not a working physics engine yet (not sync'ing with Scene yet)). private Dictionary m_loadBalancingIdleSEs = new Dictionary(); public void HandleLoadBalanceRequest(SceneToPhysEngineConnector seConnctor) @@ -616,6 +617,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule seConnctor.SendLoadBalanceRejection("no idle physics engines"); } } + */ HashSet exceptions = new HashSet(); private OSDMap DeserializeMessage(RegionSyncMessage msg) From 0dbd96a12f08741da45adfb84f7d757a6f557875 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 4 Jan 2011 10:19:21 -0800 Subject: [PATCH 13/15] Modify remote physics configuration to work with new object sync. Remove some chatty debug messages --- .../PhysEngineToSceneConnectorModule.cs | 2 +- .../SymmetricSync/RegionSyncModule.cs | 4 ++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 4 ++-- OpenSim/Region/Physics/PEPlugin/PEPrim.cs | 16 ++++++++-------- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index fa85318920..8a8a92c7d9 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -87,7 +87,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule IConfig syncConfig = config.Configs["RegionSyncModule"]; if (syncConfig != null && syncConfig.GetBoolean("Enabled", false) - && syncConfig.GetString("Mode", "").ToLower() == "client" + // && syncConfig.GetString("Mode", "").ToLower() == "client" && syncConfig.GetBoolean("PhysEngineClient", false) ) { diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 3b9ca5f3eb..ea6aaf587a 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -302,7 +302,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule #endregion //IRegionSyncModule #region ICommandableModule Members - private readonly Commander m_commander = new Commander("sync"); + private readonly Commander m_commander = new Commander("ssync"); public ICommander CommandInterface { get { return m_commander; } @@ -340,7 +340,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// Commandline arguments private void EventManager_OnPluginConsole(string[] args) { - if (args[0] == "sync") + if (args[0] == "ssync") { if (args.Length == 1) { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index c885fc4e7e..9adc419de7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -457,7 +457,7 @@ namespace OpenSim.Region.Framework.Scenes lock (m_updateList) { m_updateList[obj.UUID] = obj; - m_log.Debug("added " + obj.UUID + " to m_updateList"); + // m_log.Debug("added " + obj.UUID + " to m_updateList"); } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index bc5066fa18..1b0feec8c4 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -253,8 +253,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_taintadd = true; _parent_scene.AddPhysicsActorTaint(this); // don't do .add() here; old geoms get recycled with the same hash - m_log.DebugFormat("[PHYSICS] Created ODEPrim: n={0}, m={1}, pbs={2}, phys={3}", - primName, mesh == null ? "NULL" : "DEFINED", pbs == null ? "NULL" : "DEFINED", pisPhysical); + // m_log.DebugFormat("[PHYSICS] Created ODEPrim: n={0}, m={1}, pbs={2}, phys={3}", + // primName, mesh == null ? "NULL" : "DEFINED", pbs == null ? "NULL" : "DEFINED", pisPhysical); } public override void RequestPhysicsterseUpdate() diff --git a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs index 528ef7064c..793e098e35 100755 --- a/OpenSim/Region/Physics/PEPlugin/PEPrim.cs +++ b/OpenSim/Region/Physics/PEPlugin/PEPrim.cs @@ -81,7 +81,7 @@ public sealed class PEPrim : PhysicsActor _position = pos; _size = size; _orientation = rotation; - // SendCreatePrim(primName, parent_scene, pos, size, rotation, mesh, pbs, pisPhysical, dode); + // m_log.DebugFormat("[REMOTE PRIM ENGINE] PEPrim creation of {0}", primName); } public override bool Stopped { @@ -90,21 +90,21 @@ public sealed class PEPrim : PhysicsActor public override Vector3 Size { get { return _size; } set { _size = value; - // m_log.Debug("[RPE] PEPrim set Size"); + // m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set Size"); ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Size, _size); } } public override PrimitiveBaseShape Shape { set { _pbs = value; - m_log.Debug("[RPE] PEPrim set Shape"); + m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set Shape"); ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.Shape, _pbs); } } public override uint LocalID { set { _localID = value; - // m_log.Debug("[RPE] PEPrim set LocalID"); + // m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set LocalID"); ChangingActorID = RegionSyncServerModule.ActorID; Prop.Set(_localID, PropType.LocalID, _localID); } @@ -112,13 +112,13 @@ public sealed class PEPrim : PhysicsActor } public override bool Grabbed { set { _grabbed = value; - m_log.Debug("[RPE] PEPrim set Grabbed"); + m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set Grabbed"); Prop.Set(_localID, PropType.Grabbed, _grabbed); } } public override bool Selected { set { _selected = value; - m_log.Debug("[RPE] PEPrim set Selected"); + m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set Selected"); Prop.Set(_localID, PropType.Selected, _selected); } } @@ -131,7 +131,7 @@ public sealed class PEPrim : PhysicsActor get { return _position; } set { _position = value; ChangingActorID = RegionSyncServerModule.ActorID; - // m_log.Debug("[RPE] PEPrim set Position"); + // m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set Position"); Prop.Set(_localID, PropType.Position, _position); } } @@ -142,7 +142,7 @@ public sealed class PEPrim : PhysicsActor get { return _force; } set { _force = value; ChangingActorID = RegionSyncServerModule.ActorID; - // m_log.Debug("[RPE] PEPrim set Force"); + // m_log.Debug("[REMOTE PRIM ENGINE] PEPrim set Force"); Prop.Set(_localID, PropType.Force, _force); } } From 254436e914d8e6467024ed532d91158b56617a85 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 4 Jan 2011 16:15:55 -0800 Subject: [PATCH 14/15] Cause PhysicsterseUpdate event to happen in the persistance actor when the attributes are changed by the physics actor --- .../SceneToPhysEngineConnector.cs | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index 4df6fa5afd..611eb1ed32 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -293,7 +293,27 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private void HandlePhysTerseUpdate(RegionSyncMessage msg) { - // TODO: + OSDMap data = RegionSyncUtil.DeserializeMessage(msg, LogHeader); + try + { + uint localID = data["localID"].AsUInteger(); + // m_log.DebugFormat("{0}: received PhysUpdateAttributes for {1}", LogHeader, localID); + PhysicsActor pa = FindPhysicsActor(localID); + if (pa != null) + { + pa.RequestPhysicsterseUpdate(); + } + else + { + m_log.WarnFormat("{0}: terse update for unknown localID {1}", LogHeader, localID); + return; + } + } + catch (Exception e) + { + m_log.WarnFormat("{0}: EXCEPTION processing PhysTerseUpdate: {1}", LogHeader, e); + return; + } return; } @@ -316,7 +336,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// private void HandlePhysUpdateAttributes(RegionSyncMessage msg) { - // TODO: OSDMap data = RegionSyncUtil.DeserializeMessage(msg, LogHeader); try { @@ -339,6 +358,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule pa.Buoyancy = (float)(data["buoyancy"].AsReal()); pa.CollidingGround = data["isCollidingGround"].AsBoolean(); pa.IsColliding = data["isCollidingGround"].AsBoolean(); + + pa.RequestPhysicsterseUpdate(); // tell the system the values have changed } else { From 251592e54a7ad0ec8e3a977ce399949d2fcfd6d9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 5 Jan 2011 16:22:27 -0800 Subject: [PATCH 15/15] Code cleanup for better exception processing when looking for a scenePresence when routing a physics event --- .../PhysEngineToSceneConnectorModule.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index 8a8a92c7d9..caa6277035 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -233,7 +233,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// public static void RouteUpdate(PhysicsActor pa) { - SceneObjectPart sop = null; + SceneObjectPart sop; + ScenePresence sp; Scene s = null; foreach (Scene ss in m_allScenes) { @@ -250,13 +251,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule s = ss; break; } + try { - ScenePresence sp = ss.GetScenePresence(pa.LocalID); - if (sp != null) - { - s = ss; - break; - } + sp = ss.GetScenePresence(pa.LocalID); + } + catch + { + sp = null; + } + if (sp != null) + { + s = ss; + break; } } if (s != null) @@ -447,7 +453,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.Warn(LogHeader + " Not currently synchronized"); return; } - m_log.Warn(LogHeader + " Synchronized"); foreach (KeyValuePair pair in m_PEToSceneConnectors) { PhysEngineToSceneConnector sceneConnector = pair.Value;