diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 73036c230d..c5334316d3 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -812,12 +812,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule connector.Send(syncMsg); } - private void HandleGetObjectRequest(SyncConnector connector, SceneObjectGroup sog) + private void HandleGetObjectRequest(SyncConnector connector) { - SymmetricSyncMessage syncMsg = CreateNewObjectMessage(sog); + EntityBase[] entities = m_scene.GetEntities(); + foreach (EntityBase e in entities) + { + if (e is SceneObjectGroup) + { + SceneObjectGroup sog = (SceneObjectGroup)e; - //SendToSyncConnector(connector, sog, syncMsg); - connector.EnqueueOutgoingUpdate(sog.UUID, syncMsg.ToBytes()); + //if (connector.IsPositionInSyncQuarks(sog.AbsolutePosition)) + //{ + SymmetricSyncMessage syncMsg = NewObjectMessageEncoder(sog); + + //SendToSyncConnector(connector, sog, syncMsg); + connector.EnqueueOutgoingUpdate(sog.UUID, syncMsg.ToBytes()); + //} + } + } } //Read in configuration for which property-bucket each property belongs to, and the description of each bucket @@ -1259,9 +1271,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule bool inComingMsg = false; globalPos = CoordinatesConversionHandler(globalPos, inComingMsg); } - data["Position"] = OSDMap.FromVector3(globalPos); //This records the global GroupPosition. - - * */ + * */ + data["Position"] = OSDMap.FromVector3(globalPos); //This records the global GroupPosition. data["Size"] = OSD.FromVector3(pa.Size); //data["Position"] = OSD.FromVector3(pa.Position); @@ -1517,6 +1528,17 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } + private void SendSpecialObjectUpdateToRelevantSyncConnectors(string init_actorID, Vector3 globalPos, SymmetricSyncMessage syncMsg) + { + HashSet syncConnectors = GetSyncConnectorsForObjectUpdates(globalPos); + + foreach (SyncConnector connector in syncConnectors) + { + if (!connector.OtherSideActorID.Equals(init_actorID)) + connector.Send(syncMsg); + } + } + //Events are send out right away, without being put into the connector's outQueue first. //May need a better method for managing the outgoing messages (i.e. prioritizing object updates and events) private void SendSceneEventToRelevantSyncConnectors(string init_actorID, SymmetricSyncMessage rsm, SceneObjectGroup sog) @@ -1593,6 +1615,23 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return syncConnectors; } + /// + /// Get the set of sync connectors that connect to syncnodes whose SyncQuarks + /// cover the given global position (no need to convert the position). + /// + /// + /// + private HashSet GetSyncConnectorsForObjectUpdates(Vector3 globalPos) + { + //HashSet syncConnectors = m_syncConnectorManager.GetSyncConnectorsByPosition(globalPos); + //return syncConnectors; + + //fake an sog to pass to GetSyncConnectorsForObjectUpdates, which + //is not used at all; a temp solution before we migrate to quarks + SceneObjectGroup sog = new SceneObjectGroup(); + return GetSyncConnectorsForObjectUpdates(sog); + } + private HashSet GetSyncConnectorsForObjectUpdates(SceneObjectPart updatedPart) { return GetSyncConnectorsForObjectUpdates(updatedPart.ParentGroup); @@ -2110,6 +2149,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } case SymmetricSyncMessage.MsgType.GetObjects: { + /* EntityBase[] entities = m_scene.GetEntities(); foreach (EntityBase e in entities) { @@ -2121,6 +2161,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule HandleGetObjectRequest(syncConnector, sog); } } + * */ + HandleGetObjectRequest(syncConnector); return; } case SymmetricSyncMessage.MsgType.NewObject: @@ -2128,8 +2170,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule break; case SymmetricSyncMessage.MsgType.UpdatedObject: { - //HandleAddOrUpdateObjectBySynchronization(msg, senderActorID); - HandleUpdateObjectBySynchronization(msg, senderActorID); + //HandleUpdateObjectBySynchronization(msg, senderActorID); + HandleUpdatedObject(msg, senderActorID); return; } case SymmetricSyncMessage.MsgType.UpdatedBucketProperties: @@ -2211,40 +2253,51 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); OSDMap data = DeserializeMessage(msg); - //First, create the object group and add it to Scene - string sogxml = data["sogxml"]; - SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); - //Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); - - //m_log.DebugFormat("{0}: received NewObject sync message from {1}, for object {1}, {2}", LogHeader, senderActorID, sog.Name, sog.UUID); - - Scene.ObjectUpdateResult updateResult = m_scene.AddNewSceneObjectBySync(sog); - //if this is a relay node, forward the event + Vector3 globalPos = data["GroupPosition"].AsVector3(); if (m_isSyncRelay) { - SendSceneEventToRelevantSyncConnectors(senderActorID, msg, sog); + SendSpecialObjectUpdateToRelevantSyncConnectors(senderActorID, globalPos, msg); } - //Second, update the physics properties of each prim in the object - OSDArray partArray = (OSDArray)data["partPhysicsProperties"]; - for (int i = 0; i < partArray.Count; i++) + /* + if (!m_syncQuarkManager.IsPosInSyncQuarks(globalPos)) { - OSDMap partData = (OSDMap)partArray[i]; - UUID partUUID = partData["UUID"].AsUUID(); - - string bucketName = partData["Bucket"].AsString(); - - //m_log.DebugFormat("{0}: HandleUpdatedBucketProperties from {1}: for {2}/{3}", LogHeader, senderActorID, partUUID.ToString(), bucketName); - - BucketSyncInfo rBucketSyncInfo = new BucketSyncInfo(bucketName); - rBucketSyncInfo.LastUpdateTimeStamp = partData["LastUpdateTimeStamp"].AsLong(); - rBucketSyncInfo.LastUpdateActorID = partData["LastUpdateActorID"].AsString(); - // updatedPart.BucketSyncInfoList.Add(bucketName, rBucketSyncInfo); - - m_scene.UpdateObjectPartBucketProperties(bucketName, partUUID, data, rBucketSyncInfo); + m_log.WarnFormat("{0}: Received an update for object at global pos {1}, not within local quarks, ignore the update", LogHeader, globalPos.ToString()); + return; + } + * */ + + Object sog; + NewObjectMessageDecoder(data, out sog); + SceneObjectGroup group = (SceneObjectGroup)sog; + + } + + /// + /// Handler of UpdatedObject message. Note: for a relay node in the + /// sync topology, it won't forward the message right away. Instead, + /// the updates are applied locally, and during each heartbeat loop, + /// updated objects/prims are collected and updates are then sent out + /// from the relay node. + /// + /// + /// + private void HandleUpdatedObject(SymmetricSyncMessage msg, string senderActorID) + { + OSDMap data = DeserializeMessage(msg); + + string bucketName = data["Bucket"].AsString(); + //lock (m_stats) m_statSOGBucketIn++; + + if (m_primUpdatesPerBucketReceiver.ContainsKey(bucketName)) + { + m_primUpdatesPerBucketReceiver[bucketName](bucketName, data); + } + else + { + m_log.WarnFormat("{0}: Received an update message for properties bucket {1}, no such bucket supported", LogHeader, bucketName); } - //m_log.DebugFormat("{0}: after processing NewObject sync message from {1}, for object {1}, {2}", LogHeader, senderActorID, sog.Name, sog.UUID); } private void HandleUpdateObjectBySynchronization(SymmetricSyncMessage msg, string senderActorID) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5e7e774c9e..2c2c5d1c8b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5552,8 +5552,12 @@ namespace OpenSim.Region.Framework.Scenes } } - //NOTE: only touch the properties and BucketSyncInfo that is related to the given bucketName. Other properties and - //buckets may not be filled at all in "updatedPart". + //NOTE: + //1. Only touch the properties and BucketSyncInfo that is related to + //the given bucketName. Other properties and buckets may not be filled + //at all in "updatedPart". + //2. For GroupPosition and Position properties, if coordinates conversion + // is needed, the caller should have done that already. private void PhysicsBucketUpdateProcessor(Object updatedPartO, string bucketName) { SceneObjectPart localPart = this; @@ -5568,6 +5572,10 @@ namespace OpenSim.Region.Framework.Scenes localPart.Velocity = updatedPart.Velocity; localPart.AngularVelocity = updatedPart.AngularVelocity; localPart.RotationOffset = updatedPart.RotationOffset; + + //TEMP DEBUG + m_log.DebugFormat("SceneObjectPart.PhysicsBucketUpdateProcessor called for part {0},{1}, at GroupPos {2}", localPart.Name, localPart.UUID, localPart.GroupPosition); + return; } @@ -5585,41 +5593,65 @@ namespace OpenSim.Region.Framework.Scenes lock (m_bucketUpdateLocks[bucketName]) { - localPart.GroupPosition = data["GroupPosition"].AsVector3(); - localPart.OffsetPosition = data["OffsetPosition"].AsVector3(); - localPart.Scale = data["Scale"].AsVector3(); - localPart.Velocity = data["Velocity"].AsVector3(); - localPart.AngularVelocity = data["AngularVelocity"].AsVector3(); - localPart.RotationOffset = data["RotationOffset"].AsQuaternion(); + if (data.ContainsKey("GroupPosition")) + localPart.GroupPosition = data["GroupPosition"].AsVector3(); + if (data.ContainsKey("OffsetPosition")) + localPart.OffsetPosition = data["OffsetPosition"].AsVector3(); + if (data.ContainsKey("Scale")) + localPart.Scale = data["Scale"].AsVector3(); + if (data.ContainsKey("Velocity")) + localPart.Velocity = data["Velocity"].AsVector3(); + if (data.ContainsKey("AngularVelocity")) + localPart.AngularVelocity = data["AngularVelocity"].AsVector3(); + if (data.ContainsKey("RotationOffset")) + localPart.RotationOffset = data["RotationOffset"].AsQuaternion(); //m_log.Debug("Received Physics Bucket updates for " + localPart.Name + ","+localPart.UUID // + ". GroupPosition: " + data["GroupPosition"].AsVector3().ToString()); - if (pa != null && data.ContainsKey("PA_Acceleration")) + if (pa != null) { - pa.Size = data["Size"].AsVector3(); - pa.Position = data["Position"].AsVector3(); - pa.Force = data["Force"].AsVector3(); + if (data.ContainsKey("Size")) + pa.Size = data["Size"].AsVector3(); + if (data.ContainsKey("Position")) + pa.Position = data["Position"].AsVector3(); + if (data.ContainsKey("Force")) + pa.Force = data["Force"].AsVector3(); // pa.Velocity = data["Velocity"].AsVector3(); - pa.RotationalVelocity = data["RotationalVelocity"].AsVector3(); - pa.Acceleration = data["PA_Acceleration"].AsVector3(); - pa.Torque = data["Torque"].AsVector3(); - pa.Orientation = data["Orientation"].AsQuaternion(); - pa.IsPhysical = data["IsPhysical"].AsBoolean(); - pa.Flying = data["Flying"].AsBoolean(); - pa.Kinematic = data["Kinematic"].AsBoolean(); - pa.Buoyancy = (float)data["Buoyancy"].AsReal(); - pa.CollidingGround = data["CollidingGround"].AsBoolean(); - pa.IsColliding = data["IsColliding"].AsBoolean(); + if (data.ContainsKey("RotationalVelocity")) + pa.RotationalVelocity = data["RotationalVelocity"].AsVector3(); + if (data.ContainsKey("PA_Acceleration")) + pa.Acceleration = data["PA_Acceleration"].AsVector3(); + if (data.ContainsKey("Torque")) + pa.Torque = data["Torque"].AsVector3(); + if (data.ContainsKey("Orientation")) + pa.Orientation = data["Orientation"].AsQuaternion(); + if (data.ContainsKey("IsPhysical")) + pa.IsPhysical = data["IsPhysical"].AsBoolean(); + if (data.ContainsKey("Flying")) + pa.Flying = data["Flying"].AsBoolean(); + if (data.ContainsKey("Kinematic")) + pa.Kinematic = data["Kinematic"].AsBoolean(); + if (data.ContainsKey("Buoyancy")) + pa.Buoyancy = (float)data["Buoyancy"].AsReal(); + if (data.ContainsKey("CollidingGround")) + pa.CollidingGround = data["CollidingGround"].AsBoolean(); + if (data.ContainsKey("IsColliding")) + pa.IsColliding = data["IsColliding"].AsBoolean(); - // m_log.DebugFormat("{0}: PhysicsBucketUpdateProcessor for {2},{3}. pos={1}", , data["Position"].AsVector3().ToString(), localPart.Name, localPart.UUID); + // m_log.DebugFormat("{0}: PhysicsBucketUpdateProcessor for {2},{3}. pos={1}", , data["Position"].AsVector3().ToString(), localPart.Name, localPart.UUID); } - m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = data["LastUpdateTimeStamp"].AsLong(); - m_bucketSyncInfoList[bucketName].LastUpdateActorID = data["LastUpdateActorID"].AsString(); + if (data.ContainsKey("LastUpdateTimeStamp")) + m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = data["LastUpdateTimeStamp"].AsLong(); + if (data.ContainsKey("LastUpdateActorID")) + m_bucketSyncInfoList[bucketName].LastUpdateActorID = data["LastUpdateActorID"].AsString(); } + //TEMP DEBUG + m_log.DebugFormat("SceneObjectPart.PhysicsBucketUpdateProcessor called for part {0},{1}, at GroupPos {2}", localPart.Name, localPart.UUID, localPart.GroupPosition); + //Schedule updates to be sent out, if the local copy has just been updated //(1) if we are debugging the actor with a viewer attaching to it, //we need to schedule updates to be sent to the viewer.