123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using OpenMetaverse;
- using Nini.Config;
- using OpenSim.Framework;
- using OpenSim.Region.Framework.Interfaces;
- using OpenSim.Region.Framework.Scenes;
- using OpenSim.Region.Framework.Scenes.Serialization;
- using OpenSim.Region.Physics.Manager;
- using log4net;
- namespace OpenSim.Region.OptionalModules.ContentManagement
- {
- public class ContentManagementEntity : MetaEntity
- {
- #region Static Fields
- // static float TimeToDiff = 0;
- // static float TimeToCreateEntities = 0;
- #endregion Static Fields
- #region Fields
- protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
- protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
- // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
- // This can come in handy.
- protected SceneObjectGroup m_UnchangedEntity = null;
- /// <value>
- /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
- /// </value>
- bool DiffersFromSceneGroup = false;
- #endregion Fields
- #region Constructors
- public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
- : base(Unchanged, false)
- {
- m_UnchangedEntity = Unchanged.Copy(false);
- }
- public ContentManagementEntity(string objectXML, Scene scene, bool physics)
- : base(objectXML, scene, false)
- {
- m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML);
- }
- #endregion Constructors
- #region Public Properties
- public SceneObjectGroup UnchangedEntity
- {
- get { return m_UnchangedEntity; }
- }
- #endregion Public Properties
- #region Private Methods
- /// <summary>
- /// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
- /// </summary>
- private bool ContainsKey(List<EntityBase> list, UUID uuid)
- {
- foreach (EntityBase part in list)
- if (part.UUID == uuid)
- return true;
- return false;
- }
- private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
- {
- foreach (EntityBase ent in list)
- {
- if (ent is SceneObjectGroup)
- if (ent.UUID == uuid)
- return (SceneObjectGroup)ent;
- }
- return null;
- }
- #endregion Private Methods
- #region Public Methods
- /// <summary>
- /// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
- /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
- /// </summary>
- public void FindDifferences()
- {
- List<EntityBase> sceneEntityList = new List<EntityBase>(m_Entity.Scene.GetEntities());
- DiffersFromSceneGroup = false;
- // if group is not contained in scene's list
- if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
- {
- lock (m_UnchangedEntity.Children)
- {
- foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
- {
- // if scene list no longer contains this part, display translucent part and mark with red aura
- if (!ContainsKey(sceneEntityList, part.UUID))
- {
- // if already displaying a red aura over part, make sure its red
- if (m_AuraEntities.ContainsKey(part.UUID))
- {
- m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
- }
- else
- {
- AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
- part.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- new Vector3(254,0,0),
- part.Scale
- );
- m_AuraEntities.Add(part.UUID, auraGroup);
- }
- SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
- SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
- }
- // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
- }
- }
- // a deleted part has no where to point a beam particle system,
- // if a metapart had a particle system (maybe it represented a moved part) remove it
- if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
- {
- m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
- m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
- }
- DiffersFromSceneGroup = true;
- }
- // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
- else
- {
- MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
- }
- }
- /// <summary>
- /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
- /// </summary>
- public bool HasChildPrim(UUID uuid)
- {
- lock (m_UnchangedEntity.Children)
- if (m_UnchangedEntity.Children.ContainsKey(uuid))
- return true;
-
- return false;
- }
- /// <summary>
- /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
- /// </summary>
- public bool HasChildPrim(uint localID)
- {
- lock (m_UnchangedEntity.Children)
- {
- foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
- if (part.LocalId == localID)
- return true;
- }
-
- return false;
- }
- public override void Hide(IClientAPI client)
- {
- base.Hide(client);
- foreach (MetaEntity group in m_AuraEntities.Values)
- group.Hide(client);
- foreach (MetaEntity group in m_BeamEntities.Values)
- group.Hide(client);
- }
- public override void HideFromAll()
- {
- base.HideFromAll();
- foreach (MetaEntity group in m_AuraEntities.Values)
- group.HideFromAll();
- foreach (MetaEntity group in m_BeamEntities.Values)
- group.HideFromAll();
- }
- /// <summary>
- /// Returns true if there was a change between meta entity and the entity group, false otherwise.
- /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
- /// </summary>
- public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
- {
- SceneObjectPart sceneEntityPart;
- SceneObjectPart metaEntityPart;
- Diff differences;
- bool changed = false;
- // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
- // had originally saved.
- // m_Entity will NOT necessarily be the same entity as the user had saved.
- lock (m_UnchangedEntity.Children)
- {
- foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
- {
- //This is the part that we use to show changes.
- metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
- if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
- {
- sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
- differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
- if (differences != Diff.NONE)
- metaEntityPart.Text = "CHANGE: " + differences.ToString();
- if (differences != 0)
- {
- // Root Part that has been modified
- if ((differences&Diff.POSITION) > 0)
- {
- // If the position of any part has changed, make sure the RootPart of the
- // meta entity is pointing with a beam particle system
- if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
- {
- m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
- m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
- }
- BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
- m_UnchangedEntity.RootPart.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- sceneEntityPart,
- new Vector3(0,0,254)
- );
- m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
- }
-
- if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
- {
- m_AuraEntities[UnchangedPart.UUID].HideFromAll();
- m_AuraEntities.Remove(UnchangedPart.UUID);
- }
- AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
- UnchangedPart.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- new Vector3(0,0,254),
- UnchangedPart.Scale
- );
- m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
- SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
-
- DiffersFromSceneGroup = true;
- }
- else // no differences between scene part and meta part
- {
- if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
- {
- m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
- m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
- }
- if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
- {
- m_AuraEntities[UnchangedPart.UUID].HideFromAll();
- m_AuraEntities.Remove(UnchangedPart.UUID);
- }
- SetPartTransparency(metaEntityPart, MetaEntity.NONE);
- }
- }
- else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
- {
- if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
- {
- m_AuraEntities[UnchangedPart.UUID].HideFromAll();
- m_AuraEntities.Remove(UnchangedPart.UUID);
- }
- AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
- UnchangedPart.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- new Vector3(254,0,0),
- UnchangedPart.Scale
- );
- m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
- SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
-
- DiffersFromSceneGroup = true;
- }
- }
- }
-
- return changed;
- }
- public void SendFullAuraUpdate(IClientAPI client)
- {
- if (DiffersFromSceneGroup)
- {
- foreach (AuraMetaEntity group in m_AuraEntities.Values)
- group.SendFullUpdate(client);
- }
- }
- public void SendFullAuraUpdateToAll()
- {
- if (DiffersFromSceneGroup)
- {
- foreach (AuraMetaEntity group in m_AuraEntities.Values)
- group.SendFullUpdateToAll();
- }
- }
- public void SendFullBeamUpdate(IClientAPI client)
- {
- if (DiffersFromSceneGroup)
- {
- foreach (BeamMetaEntity group in m_BeamEntities.Values)
- group.SendFullUpdate(client);
- }
- }
- public void SendFullBeamUpdateToAll()
- {
- if (DiffersFromSceneGroup)
- {
- foreach (BeamMetaEntity group in m_BeamEntities.Values)
- group.SendFullUpdateToAll();
- }
- }
- public void SendFullDiffUpdate(IClientAPI client)
- {
- FindDifferences();
- if (DiffersFromSceneGroup)
- {
- SendFullUpdate(client);
- SendFullAuraUpdate(client);
- SendFullBeamUpdate(client);
- }
- }
- public void SendFullDiffUpdateToAll()
- {
- FindDifferences();
- if (DiffersFromSceneGroup)
- {
- SendFullUpdateToAll();
- SendFullAuraUpdateToAll();
- SendFullBeamUpdateToAll();
- }
- }
- #endregion Public Methods
- }
- }
|