diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules')
14 files changed, 2620 insertions, 2284 deletions
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs index 2155b4c..3188c6c 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs | |||
@@ -1,114 +1,136 @@ | |||
1 | #region Header | ||
2 | |||
1 | // AuraMetaEntity.cs created with MonoDevelop | 3 | // AuraMetaEntity.cs created with MonoDevelop |
2 | // User: bongiojp at 3:03 PM 8/6/2008 | 4 | // User: bongiojp at 3:03 PM 8/6/2008 |
3 | // | 5 | // |
4 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers | 6 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers |
5 | // | 7 | // |
6 | 8 | ||
9 | #endregion Header | ||
10 | |||
7 | using System; | 11 | using System; |
8 | using System.Collections.Generic; | 12 | using System.Collections.Generic; |
9 | using System.Drawing; | 13 | using System.Drawing; |
14 | |||
10 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
11 | using Nini.Config; | 17 | using Nini.Config; |
18 | |||
12 | using OpenSim.Framework; | 19 | using OpenSim.Framework; |
13 | using OpenSim.Region.Environment.Interfaces; | 20 | using OpenSim.Region.Environment.Interfaces; |
14 | using OpenSim.Region.Environment.Scenes; | 21 | using OpenSim.Region.Environment.Scenes; |
15 | using log4net; | ||
16 | using OpenSim.Region.Physics.Manager; | 22 | using OpenSim.Region.Physics.Manager; |
23 | |||
24 | using log4net; | ||
25 | |||
17 | using Axiom.Math; | 26 | using Axiom.Math; |
18 | 27 | ||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 28 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
20 | { | 29 | { |
21 | 30 | public class AuraMetaEntity : PointMetaEntity | |
22 | 31 | { | |
23 | public class AuraMetaEntity : PointMetaEntity | 32 | #region Constructors |
24 | { | 33 | |
25 | //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency. | 34 | //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency. |
26 | public AuraMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale) : base(scene, LocalId, groupPos, transparency) | 35 | public AuraMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale) |
27 | { | 36 | : base(scene, LocalId, groupPos, transparency) |
28 | SetAura(color, scale); | 37 | { |
29 | } | 38 | SetAura(color, scale); |
30 | 39 | } | |
31 | public AuraMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale) : base(scene, uuid, LocalId, groupPos, transparency) | 40 | |
32 | { | 41 | public AuraMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale) |
33 | SetAura(color, scale); | 42 | : base(scene, uuid, LocalId, groupPos, transparency) |
34 | } | 43 | { |
35 | 44 | SetAura(color, scale); | |
36 | private float Average(LLVector3 values) | 45 | } |
37 | { | 46 | |
38 | return (values.X + values.Y + values.Z)/3f; | 47 | #endregion Constructors |
39 | } | 48 | |
40 | 49 | #region Private Methods | |
41 | public void SetAura(LLVector3 color, LLVector3 scale) | 50 | |
42 | { | 51 | private float Average(LLVector3 values) |
43 | SetAura(color, Average(scale) * 2.0f); | 52 | { |
44 | } | 53 | return (values.X + values.Y + values.Z)/3f; |
45 | 54 | } | |
46 | public void SetAura(LLVector3 color, float radius) | 55 | |
47 | { | 56 | #endregion Private Methods |
48 | SceneObjectPart From = m_Entity.RootPart; | 57 | |
49 | 58 | #region Public Methods | |
50 | //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius); | 59 | |
51 | float burstRadius = 0.1f; | 60 | public void SetAura(LLVector3 color, LLVector3 scale) |
52 | Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None; | 61 | { |
53 | float age = 1.5f; | 62 | SetAura(color, Average(scale) * 2.0f); |
54 | float burstRate = 0.4f; | 63 | } |
55 | if (radius >= 8.0f) | 64 | |
56 | { | 65 | public void SetAura(LLVector3 color, float radius) |
57 | //float sizeOfObject = radius / 2.0f; | 66 | { |
58 | burstRadius = (radius - 8.0f)/3f; | 67 | SceneObjectPart From = m_Entity.RootPart; |
59 | burstRate = 1.5f; | 68 | |
60 | radius = 7.99f; | 69 | //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius); |
61 | patternFlags = Primitive.ParticleSystem.SourcePattern.Explode; | 70 | float burstRadius = 0.1f; |
62 | age = 4.0f; | 71 | Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None; |
63 | } | 72 | float age = 1.5f; |
64 | SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags); | 73 | float burstRate = 0.4f; |
65 | } | 74 | if (radius >= 8.0f) |
66 | public void SetAura(SceneObjectPart From, LLVector3 color, float radius, float burstRadius, float age, float burstRate, libsecondlife.Primitive.ParticleSystem.SourcePattern patternFlags) | 75 | { |
67 | { | 76 | //float sizeOfObject = radius / 2.0f; |
68 | Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); | 77 | burstRadius = (radius - 8.0f)/3f; |
69 | //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | | 78 | burstRate = 1.5f; |
70 | // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS | 79 | radius = 7.99f; |
71 | //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | | 80 | patternFlags = Primitive.ParticleSystem.SourcePattern.Explode; |
72 | // Primitive.ParticleSystem.ParticleDataFlags.TargetPos; | 81 | age = 4.0f; |
73 | prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR | 82 | } |
74 | prules.PartStartColor.G = color.Y; | 83 | SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags); |
75 | prules.PartStartColor.B = color.Z; | 84 | } |
76 | prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency | 85 | |
77 | prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR | 86 | public void SetAura(SceneObjectPart From, LLVector3 color, float radius, float burstRadius, float age, float burstRate, libsecondlife.Primitive.ParticleSystem.SourcePattern patternFlags) |
78 | prules.PartEndColor.G = color.Y; | 87 | { |
79 | prules.PartEndColor.B = color.Z; | 88 | Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); |
80 | prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency | 89 | //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | |
81 | /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE | 90 | // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS |
82 | prules.PartStartScaleY = 0.5f; | 91 | //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | |
83 | prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE | 92 | // Primitive.ParticleSystem.ParticleDataFlags.TargetPos; |
84 | prules.PartEndScaleY = 0.5f; | 93 | prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR |
85 | */ | 94 | prules.PartStartColor.G = color.Y; |
86 | prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE | 95 | prules.PartStartColor.B = color.Z; |
87 | prules.PartStartScaleY = radius; | 96 | prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency |
88 | prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE | 97 | prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR |
89 | prules.PartEndScaleY = radius; | 98 | prules.PartEndColor.G = color.Y; |
90 | prules.PartMaxAge = age; //PSYS_PART_MAX_AGE | 99 | prules.PartEndColor.B = color.Z; |
91 | prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL | 100 | prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency |
92 | prules.PartAcceleration.Y = 0.0f; | 101 | /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE |
93 | prules.PartAcceleration.Z = 0.0f; | 102 | prules.PartStartScaleY = 0.5f; |
94 | prules.Pattern = patternFlags; //PSYS_SRC_PATTERN | 103 | prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE |
95 | //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank | 104 | prules.PartEndScaleY = 0.5f; |
96 | prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE | 105 | */ |
97 | prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT | 106 | prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE |
98 | //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS | 107 | prules.PartStartScaleY = radius; |
99 | prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS | 108 | prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE |
100 | prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN | 109 | prules.PartEndScaleY = radius; |
110 | prules.PartMaxAge = age; //PSYS_PART_MAX_AGE | ||
111 | prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL | ||
112 | prules.PartAcceleration.Y = 0.0f; | ||
113 | prules.PartAcceleration.Z = 0.0f; | ||
114 | prules.Pattern = patternFlags; //PSYS_SRC_PATTERN | ||
115 | //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank | ||
116 | prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE | ||
117 | prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT | ||
118 | //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS | ||
119 | prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS | ||
120 | prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN | ||
101 | prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX | 121 | prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX |
102 | prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE | 122 | prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE |
103 | //prules.Target = To; //PSYS_SRC_TARGET_KEY | 123 | //prules.Target = To; //PSYS_SRC_TARGET_KEY |
104 | prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA | 124 | prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA |
105 | prules.AngularVelocity.Y = 0.0f; | 125 | prules.AngularVelocity.Y = 0.0f; |
106 | prules.AngularVelocity.Z = 0.0f; | 126 | prules.AngularVelocity.Z = 0.0f; |
107 | prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN | 127 | prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN |
108 | prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END | 128 | prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END |
109 | 129 | ||
110 | prules.CRC = 1; //activates the particle system?? | 130 | prules.CRC = 1; //activates the particle system?? |
111 | From.AddNewParticleSystem(prules); | 131 | From.AddNewParticleSystem(prules); |
112 | } | 132 | } |
113 | } | 133 | |
114 | } | 134 | #endregion Public Methods |
135 | } | ||
136 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs index 499d1bc..cea9550 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs | |||
@@ -1,98 +1,114 @@ | |||
1 | #region Header | ||
2 | |||
1 | // BeamMetaEntity.cs created with MonoDevelop | 3 | // BeamMetaEntity.cs created with MonoDevelop |
2 | // User: bongiojp at 3:03 PM 8/6/2008 | 4 | // User: bongiojp at 3:03 PM 8/6/2008 |
3 | // | 5 | // |
4 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers | 6 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers |
5 | // | 7 | // |
6 | 8 | ||
9 | #endregion Header | ||
10 | |||
7 | using System; | 11 | using System; |
8 | using System.Collections.Generic; | 12 | using System.Collections.Generic; |
9 | using System.Drawing; | 13 | using System.Drawing; |
14 | |||
10 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
11 | using Nini.Config; | 17 | using Nini.Config; |
18 | |||
12 | using OpenSim.Framework; | 19 | using OpenSim.Framework; |
13 | using OpenSim.Region.Environment.Interfaces; | 20 | using OpenSim.Region.Environment.Interfaces; |
14 | using OpenSim.Region.Environment.Scenes; | 21 | using OpenSim.Region.Environment.Scenes; |
15 | using log4net; | ||
16 | using OpenSim.Region.Physics.Manager; | 22 | using OpenSim.Region.Physics.Manager; |
23 | |||
24 | using log4net; | ||
25 | |||
17 | using Axiom.Math; | 26 | using Axiom.Math; |
18 | 27 | ||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 28 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
20 | { | 29 | { |
21 | 30 | public class BeamMetaEntity : PointMetaEntity | |
22 | 31 | { | |
23 | public class BeamMetaEntity : PointMetaEntity | 32 | #region Constructors |
24 | { | 33 | |
25 | 34 | public BeamMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color) | |
26 | public BeamMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color) : base(scene, LocalId, groupPos, transparency) | 35 | : base(scene, LocalId, groupPos, transparency) |
27 | { | 36 | { |
28 | SetBeamToUUID(To, color); | 37 | SetBeamToUUID(To, color); |
29 | } | 38 | } |
30 | 39 | ||
31 | public BeamMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color) : base(scene, uuid, LocalId, groupPos, transparency) | 40 | public BeamMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color) |
32 | { | 41 | : base(scene, uuid, LocalId, groupPos, transparency) |
33 | SetBeamToUUID(To, color); | 42 | { |
34 | } | 43 | SetBeamToUUID(To, color); |
35 | 44 | } | |
36 | public void SetBeamToUUID(SceneObjectPart To, LLVector3 color) | 45 | |
37 | { | 46 | #endregion Constructors |
38 | SceneObjectPart From = m_Entity.RootPart; | 47 | |
39 | //Scale size of particles to distance objects are apart (for better visibility) | 48 | #region Public Methods |
40 | LLVector3 FromPos = From.GetWorldPosition(); | 49 | |
41 | LLVector3 ToPos = From.GetWorldPosition(); | 50 | public void SetBeamToUUID(SceneObjectPart To, LLVector3 color) |
42 | LLUUID toUUID = To.UUID; | 51 | { |
43 | float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) + | 52 | SceneObjectPart From = m_Entity.RootPart; |
44 | Math.Pow(FromPos.X-ToPos.Y, 2) + | 53 | //Scale size of particles to distance objects are apart (for better visibility) |
45 | Math.Pow(FromPos.X-ToPos.Z, 2) | 54 | LLVector3 FromPos = From.GetWorldPosition(); |
46 | ) | 55 | LLVector3 ToPos = From.GetWorldPosition(); |
47 | ); | 56 | LLUUID toUUID = To.UUID; |
48 | //float rate = (float) (distance/4f); | 57 | float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) + |
49 | float rate = 0.5f; | 58 | Math.Pow(FromPos.X-ToPos.Y, 2) + |
50 | float scale = (float) (distance/128f); | 59 | Math.Pow(FromPos.X-ToPos.Z, 2) |
51 | float speed = (float) (2.0f - distance/128f); | 60 | ) |
52 | 61 | ); | |
53 | SetBeamToUUID(From, To, color, rate, scale, speed); | 62 | //float rate = (float) (distance/4f); |
54 | } | 63 | float rate = 0.5f; |
55 | 64 | float scale = (float) (distance/128f); | |
56 | public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, LLVector3 color, float rate, float scale, float speed) | 65 | float speed = (float) (2.0f - distance/128f); |
57 | { | 66 | |
58 | Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); | 67 | SetBeamToUUID(From, To, color, rate, scale, speed); |
59 | //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | | 68 | } |
60 | // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS | 69 | |
61 | prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | | 70 | public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, LLVector3 color, float rate, float scale, float speed) |
62 | Primitive.ParticleSystem.ParticleDataFlags.TargetPos; | 71 | { |
63 | prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR | 72 | Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); |
64 | prules.PartStartColor.G = color.Y; | 73 | //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | |
65 | prules.PartStartColor.B = color.Z; | 74 | // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS |
66 | prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency | 75 | prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | |
67 | prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR | 76 | Primitive.ParticleSystem.ParticleDataFlags.TargetPos; |
68 | prules.PartEndColor.G = color.Y; | 77 | prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR |
69 | prules.PartEndColor.B = color.Z; | 78 | prules.PartStartColor.G = color.Y; |
70 | prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency | 79 | prules.PartStartColor.B = color.Z; |
71 | prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE | 80 | prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency |
72 | prules.PartStartScaleY = scale; | 81 | prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR |
73 | prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE | 82 | prules.PartEndColor.G = color.Y; |
74 | prules.PartEndScaleY = scale; | 83 | prules.PartEndColor.B = color.Z; |
75 | prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE | 84 | prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency |
76 | prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL | 85 | prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE |
77 | prules.PartAcceleration.Y = 0.0f; | 86 | prules.PartStartScaleY = scale; |
78 | prules.PartAcceleration.Z = 0.0f; | 87 | prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE |
79 | //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN | 88 | prules.PartEndScaleY = scale; |
80 | //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank | 89 | prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE |
81 | prules.BurstRate = rate; //PSYS_SRC_BURST_RATE | 90 | prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL |
82 | prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT | 91 | prules.PartAcceleration.Y = 0.0f; |
83 | prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS | 92 | prules.PartAcceleration.Z = 0.0f; |
84 | prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN | 93 | //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN |
94 | //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank | ||
95 | prules.BurstRate = rate; //PSYS_SRC_BURST_RATE | ||
96 | prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT | ||
97 | prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS | ||
98 | prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN | ||
85 | prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX | 99 | prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX |
86 | prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE | 100 | prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE |
87 | prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY | 101 | prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY |
88 | prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA | 102 | prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA |
89 | prules.AngularVelocity.Y = 0.0f; | 103 | prules.AngularVelocity.Y = 0.0f; |
90 | prules.AngularVelocity.Z = 0.0f; | 104 | prules.AngularVelocity.Z = 0.0f; |
91 | prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN | 105 | prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN |
92 | prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END | 106 | prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END |
93 | 107 | ||
94 | prules.CRC = 1; //activates the particle system?? | 108 | prules.CRC = 1; //activates the particle system?? |
95 | From.AddNewParticleSystem(prules); | 109 | From.AddNewParticleSystem(prules); |
96 | } | 110 | } |
97 | } | 111 | |
98 | } | 112 | #endregion Public Methods |
113 | } | ||
114 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs index d3ca3cf..a179fb1 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs | |||
@@ -1,684 +1,721 @@ | |||
1 | #region Header | ||
2 | |||
1 | // CMController.cs | 3 | // CMController.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | // | 5 | // |
4 | 6 | ||
7 | #endregion Header | ||
8 | |||
5 | using System; | 9 | using System; |
6 | using System.Collections.Generic; | ||
7 | using System.Collections; | 10 | using System.Collections; |
11 | using System.Collections.Generic; | ||
12 | using System.Diagnostics; | ||
13 | using System.Threading; | ||
14 | |||
8 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
9 | using OpenSim; | 17 | using OpenSim; |
10 | using OpenSim.Framework; | 18 | using OpenSim.Framework; |
11 | using OpenSim.Region.Environment.Interfaces; | 19 | using OpenSim.Region.Environment.Interfaces; |
12 | using OpenSim.Region.Environment.Scenes; | 20 | using OpenSim.Region.Environment.Scenes; |
13 | using log4net; | ||
14 | using OpenSim.Region.Physics.Manager; | 21 | using OpenSim.Region.Physics.Manager; |
22 | |||
23 | using log4net; | ||
24 | |||
15 | using Axiom.Math; | 25 | using Axiom.Math; |
16 | using System.Threading; | ||
17 | using System.Diagnostics; | ||
18 | 26 | ||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 27 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
20 | { | 28 | { |
21 | 29 | /// <summary> | |
22 | /// <summary> | 30 | /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread, |
23 | /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread, | 31 | /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system. |
24 | /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system. | 32 | /// </summary> |
25 | /// </summary> | 33 | public class CMController |
26 | public class CMController | 34 | { |
27 | { | 35 | #region Static Fields |
28 | 36 | ||
29 | /// <value> | 37 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
30 | /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem. | 38 | |
31 | /// </value> | 39 | /// <value> |
32 | private struct Work | 40 | /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue. |
33 | { | 41 | /// </value> |
34 | public WorkType Type; | 42 | private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>(); |
35 | public Object Data1; //Just space for holding data. | 43 | |
36 | public Object Data2; //Just more space for holding data. | 44 | #endregion Static Fields |
37 | public uint LocalId; //Convenient | 45 | |
38 | public LLUUID UUID; //Convenient | 46 | #region Fields |
39 | } | 47 | |
40 | 48 | bool init = false; | |
41 | /// <value> | 49 | int m_channel = -1; |
42 | /// Identifies what the data in struct Work should be used for. | 50 | |
43 | /// </value> | 51 | /// <value> |
44 | private enum WorkType | 52 | /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers. |
45 | { | 53 | /// </value> |
46 | NONE, | 54 | IEstateModule m_estateModule = null; |
47 | OBJECTATTRIBUTECHANGE, | 55 | |
48 | PRIMITIVEADDED, | 56 | //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop) |
49 | OBJECTDUPLICATED, | 57 | CMModel m_model = null; |
50 | OBJECTKILLED, | 58 | |
51 | UNDODID, | 59 | /// <value> |
52 | NEWCLIENT, | 60 | /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region. |
53 | SIMCHAT | 61 | /// </value> |
54 | } | 62 | Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable()); |
55 | 63 | State m_state = State.NONE; | |
56 | /// <value> | 64 | Thread m_thread = null; |
57 | /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk. | 65 | CMView m_view = null; |
58 | /// </value> | 66 | |
59 | [Flags] | 67 | #endregion Fields |
60 | private enum State | 68 | |
61 | { | 69 | #region Constructors |
62 | NONE = 0, | 70 | |
63 | DIRTY = 1, // The meta entities may not correctly represent the last revision. | 71 | /// <summary> |
64 | SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user. | 72 | /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method. |
65 | } | 73 | /// </summary> |
66 | 74 | /// <param name="model"> | |
67 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 75 | /// <see cref="CMModel"/> |
68 | 76 | /// </param> | |
69 | /// <value> | 77 | /// <param name="view"> |
70 | /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue. | 78 | /// <see cref="CMView"/> |
71 | /// </value> | 79 | /// </param> |
72 | private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>(); | 80 | /// <param name="scene"> |
73 | 81 | /// The first scene to keep track of. <see cref="Scene"/> | |
74 | /// <value> | 82 | /// </param> |
75 | /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region. | 83 | /// <param name="channel"> |
76 | /// </value> | 84 | /// The simchat channel number to listen to for instructions <see cref="System.Int32"/> |
77 | Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable()); | 85 | /// </param> |
78 | 86 | public CMController(CMModel model, CMView view, Scene scene, int channel) | |
79 | /// <value> | 87 | { |
80 | /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers. | 88 | m_model = model; m_view = view; m_channel = channel; |
81 | /// </value> | 89 | RegisterNewRegion(scene); |
82 | IEstateModule m_estateModule = null; | 90 | Initialize(model, view, scene, channel); |
83 | 91 | } | |
84 | Thread m_thread = null; | 92 | |
85 | State m_state = State.NONE; | 93 | #endregion Constructors |
86 | bool init = false; | 94 | |
87 | 95 | #region Private Methods | |
88 | //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop) | 96 | |
89 | CMModel m_model = null; | 97 | //------------------------------------------------ EVENTS ----------------------------------------------------// |
90 | CMView m_view = null; | 98 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) |
91 | int m_channel = -1; | 99 | { |
92 | 100 | } | |
93 | /// <summary> | 101 | |
94 | /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method. | 102 | /// <summary> |
95 | /// </summary> | 103 | /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned. |
96 | /// <param name="model"> | 104 | /// </summary> |
97 | /// <see cref="CMModel"/> | 105 | private SceneObjectGroup GetGroupByPrim(uint localID) |
98 | /// </param> | 106 | { |
99 | /// <param name="view"> | 107 | foreach(Object currScene in m_sceneList.Values) |
100 | /// <see cref="CMView"/> | 108 | { |
101 | /// </param> | 109 | foreach (EntityBase ent in ((Scene)currScene).GetEntities()) |
102 | /// <param name="scene"> | 110 | { |
103 | /// The first scene to keep track of. <see cref="Scene"/> | 111 | if (ent is SceneObjectGroup) |
104 | /// </param> | 112 | { |
105 | /// <param name="channel"> | 113 | if (((SceneObjectGroup)ent).HasChildPrim(localID)) |
106 | /// The simchat channel number to listen to for instructions <see cref="System.Int32"/> | 114 | return (SceneObjectGroup)ent; |
107 | /// </param> | 115 | } |
108 | public CMController(CMModel model, CMView view, Scene scene, int channel) | 116 | } |
109 | { | 117 | } |
110 | m_model = model; m_view = view; m_channel = channel; | ||
111 | RegisterNewRegion(scene); | ||
112 | Initialize(model, view, scene, channel); | ||
113 | } | ||
114 | |||
115 | private void Initialize(CMModel model, CMView view, Scene scene, int channel) | ||
116 | { | ||
117 | lock(this) | ||
118 | { | ||
119 | m_estateModule = scene.RequestModuleInterface<IEstateModule>(); | ||
120 | m_thread = new Thread( MainLoop ); | ||
121 | m_thread.Name = "Content Management"; | ||
122 | m_thread.IsBackground = true; | ||
123 | m_thread.Start(); | ||
124 | ThreadTracker.Add(m_thread); | ||
125 | m_state = State.NONE; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | /// <summary> | ||
130 | /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene. | ||
131 | /// </summary> | ||
132 | /// <param name="scene"> | ||
133 | /// A <see cref="Scene"/> | ||
134 | /// </param> | ||
135 | public void RegisterNewRegion(Scene scene) | ||
136 | { | ||
137 | m_sceneList.Add(scene.RegionInfo.RegionID, scene); | ||
138 | |||
139 | m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID); | ||
140 | m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System."); | ||
141 | |||
142 | scene.EventManager.OnNewClient += StartManaging; | ||
143 | scene.EventManager.OnRemovePresence += StopManaging; | ||
144 | // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | ||
145 | scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted; | ||
146 | } | ||
147 | |||
148 | /// <summary> | ||
149 | /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions. | ||
150 | /// </summary> | ||
151 | private void MainLoop() | ||
152 | { | ||
153 | CMModel model = m_model; CMView view = m_view; int channel = m_channel; | ||
154 | Work currentJob = new Work(); | ||
155 | while(true) | ||
156 | { | ||
157 | currentJob = m_WorkQueue.Dequeue(); | ||
158 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request"); | ||
159 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type); | ||
160 | switch(currentJob.Type) | ||
161 | { | ||
162 | case WorkType.NONE: | ||
163 | break; | ||
164 | case WorkType.OBJECTATTRIBUTECHANGE: | ||
165 | ObjectAttributeChanged(model, view, currentJob.LocalId); | ||
166 | break; | ||
167 | case WorkType.PRIMITIVEADDED: | ||
168 | PrimitiveAdded(model, view, currentJob); | ||
169 | break; | ||
170 | case WorkType.OBJECTDUPLICATED: | ||
171 | ObjectDuplicated(model, view, currentJob.LocalId); | ||
172 | break; | ||
173 | case WorkType.OBJECTKILLED: | ||
174 | ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1); | ||
175 | break; | ||
176 | case WorkType.UNDODID: | ||
177 | UndoDid(model, view, currentJob.UUID); | ||
178 | break; | ||
179 | case WorkType.NEWCLIENT: | ||
180 | NewClient(view, (IClientAPI) currentJob.Data1); | ||
181 | break; | ||
182 | case WorkType.SIMCHAT: | ||
183 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message); | ||
184 | SimChat(model, view, (OSChatMessage) currentJob.Data1, channel); | ||
185 | break; | ||
186 | default: | ||
187 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?"); | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
193 | /// <summary> | ||
194 | /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled. | ||
195 | /// </summary> | ||
196 | private void NewClient(CMView view, IClientAPI client) | ||
197 | { | ||
198 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
199 | view.SendMetaEntitiesToNewClient(client); | ||
200 | } | ||
201 | |||
202 | /// <summary> | ||
203 | /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied. | ||
204 | /// </summary> | ||
205 | private void ObjectDuplicated(CMModel model, CMView view, uint localId) | ||
206 | { | ||
207 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
208 | view.DisplayAuras(model.CheckForNewEntitiesMissingAuras( GetGroupByPrim(localId).Scene )); | ||
209 | } | ||
210 | |||
211 | /// <summary> | ||
212 | /// Only called by the MainLoop. | ||
213 | /// </summary> | ||
214 | private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group) | ||
215 | { | ||
216 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
217 | { | ||
218 | view.RemoveOrUpdateDeletedEntity(group); | ||
219 | model.RemoveOrUpdateDeletedEntity(group); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /// <summary> | ||
224 | /// Only called by the MainLoop. | ||
225 | /// </summary> | ||
226 | private void UndoDid(CMModel model, CMView view, LLUUID uuid) | ||
227 | { | ||
228 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
229 | { | ||
230 | ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid); | ||
231 | if (ent != null) | ||
232 | view.DisplayEntity(ent); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /// <summary> | ||
237 | /// Only called by the MainLoop. | ||
238 | /// </summary> | ||
239 | private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId) | ||
240 | { | ||
241 | SceneObjectGroup group = null; | ||
242 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
243 | { | ||
244 | group = GetGroupByPrim(LocalId); | ||
245 | if (group != null) | ||
246 | { | ||
247 | view.DisplayAuras( model.UpdateNormalEntityEffects(group) ); //Might be a normal entity (green aura) | ||
248 | m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura) | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | |||
253 | /// <summary> | ||
254 | /// Only called by the MainLoop. | ||
255 | /// </summary> | ||
256 | private void PrimitiveAdded(CMModel model, CMView view, Work currentJob) | ||
257 | { | ||
258 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
259 | { | ||
260 | foreach(Object scene in m_sceneList.Values) | ||
261 | m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene)); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /// <summary> | ||
266 | /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command. | ||
267 | /// </summary> | ||
268 | public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel) | ||
269 | { | ||
270 | if (e.Channel != channel) | ||
271 | return; | ||
272 | if (e.Sender == null) | ||
273 | return; | ||
274 | |||
275 | m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message); | ||
276 | |||
277 | IClientAPI client = e.Sender; | ||
278 | Scene scene = (Scene) e.Scene; | ||
279 | string message = e.Message; | ||
280 | string[] args = e.Message.Split(new char[] {' '}); | ||
281 | |||
282 | ScenePresence avatar = scene.GetScenePresence(client.AgentId); | ||
283 | |||
284 | if (!(m_estateModule.IsManager(avatar.UUID))) | ||
285 | { | ||
286 | m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring."); | ||
287 | view.SendSimChatMessage(scene, "You must be an estate manager to perform that action."); | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | switch(args[0]) | ||
292 | { | ||
293 | case "ci": | ||
294 | case "commit": | ||
295 | commit(message, scene, model, view); | ||
296 | break; | ||
297 | case "dm": | ||
298 | case "diff-mode": | ||
299 | diffmode(scene, model, view); | ||
300 | break; | ||
301 | case "rb": | ||
302 | case "rollback": | ||
303 | rollback(scene, model, view); | ||
304 | break; | ||
305 | case "help": | ||
306 | m_view.DisplayHelpMenu(scene); | ||
307 | break; | ||
308 | default: | ||
309 | view.SendSimChatMessage(scene, "Command not found: " + args[0]); | ||
310 | break; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /// <summary> | ||
315 | /// Only called from within the SimChat method. Hides all auras and meta entities, | ||
316 | /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene, | ||
317 | /// then lets the view update the clients of the new objects. | ||
318 | /// </summary> | ||
319 | protected void rollback(Scene scene, CMModel model, CMView view) | ||
320 | { | ||
321 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
322 | { | ||
323 | view.HideAllAuras(); | ||
324 | view.HideAllMetaEntities(); | ||
325 | } | ||
326 | |||
327 | System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene); | ||
328 | foreach(Scene currScene in proximitySceneList) | ||
329 | model.RollbackRegion(currScene); | ||
330 | |||
331 | if ((m_state & State.DIRTY) != 0 ) | ||
332 | { | ||
333 | model.DeleteAllMetaObjects(); | ||
334 | foreach(Scene currScene in proximitySceneList) | ||
335 | model.UpdateCMEntities(currScene); | ||
336 | } | ||
337 | |||
338 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
339 | view.DisplayRecentChanges(); | ||
340 | |||
341 | } | ||
342 | |||
343 | /// <summary> | ||
344 | /// Only called from within the SimChat method. | ||
345 | /// </summary> | ||
346 | protected void diffmode(Scene scene, CMModel model, CMView view) | ||
347 | { | ||
348 | System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene); | ||
349 | |||
350 | if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF | ||
351 | { | ||
352 | view.SendSimChatMessage(scene, "Hiding all meta objects."); | ||
353 | view.HideAllMetaEntities(); | ||
354 | view.HideAllAuras(); | ||
355 | view.SendSimChatMessage(scene, "Diff-mode = OFF"); | ||
356 | |||
357 | m_state &= ~State.SHOWING_CHANGES; | ||
358 | return; | ||
359 | } | ||
360 | else // TURN ON | ||
361 | { | ||
362 | if ((m_state & State.DIRTY) != 0 || m_state == State.NONE) | ||
363 | { | ||
364 | view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision"); | ||
365 | //Hide objects from users and Forget about them | ||
366 | view.HideAllMetaEntities(); | ||
367 | view.HideAllAuras(); | ||
368 | model.DeleteAllMetaObjects(); | ||
369 | //Recreate them from backend files | ||
370 | foreach(Object currScene in m_sceneList.Values) | ||
371 | model.UpdateCMEntities((Scene) currScene); | ||
372 | } | ||
373 | else if ((m_state & State.DIRTY) != 0) { | ||
374 | view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision"); | ||
375 | foreach(Scene currScene in proximitySceneList) | ||
376 | model.UpdateCMEntities(currScene); | ||
377 | } | ||
378 | |||
379 | view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment"); | ||
380 | foreach(Scene currScene in proximitySceneList) | ||
381 | model.CheckForNewEntitiesMissingAuras(currScene); | ||
382 | view.DisplayRecentChanges(); | ||
383 | |||
384 | view.SendSimChatMessage(scene, "Diff-mode = ON"); | ||
385 | m_state |= State.SHOWING_CHANGES; | ||
386 | m_state &= ~State.DIRTY; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | /// <summary> | ||
391 | /// Only called from within the SimChat method. | ||
392 | /// </summary> | ||
393 | protected void commit(string message, Scene scene, CMModel model, CMView view) | ||
394 | { | ||
395 | System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene); | ||
396 | |||
397 | string[] args = message.Split(new char[] {' '}); | ||
398 | |||
399 | char[] logMessage = {' '}; | ||
400 | if (args.Length > 1) | ||
401 | { | ||
402 | logMessage = new char[message.Length - (args[0].Length)]; | ||
403 | message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length)); | ||
404 | } | ||
405 | |||
406 | m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region."); | ||
407 | foreach(Scene currScene in proximitySceneList) | ||
408 | { | ||
409 | model.CommitRegion(currScene, new String(logMessage)); | ||
410 | view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName); | ||
411 | } | ||
412 | |||
413 | view.SendSimChatMessage(scene, "Successfully saved all regions."); | ||
414 | m_state |= State.DIRTY; | ||
415 | |||
416 | if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES | ||
417 | { | ||
418 | view.SendSimChatMessage(scene, "Updating differences between new revision and current environment."); | ||
419 | //Hide objects from users and Forget about them | ||
420 | view.HideAllMetaEntities(); | ||
421 | view.HideAllAuras(); | ||
422 | model.DeleteAllMetaObjects(); | ||
423 | |||
424 | //Recreate them from backend files | ||
425 | foreach(Scene currScene in proximitySceneList) | ||
426 | { | ||
427 | model.UpdateCMEntities(currScene); | ||
428 | view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName); | ||
429 | } | ||
430 | |||
431 | //Display new objects to users1 | ||
432 | view.DisplayRecentChanges(); | ||
433 | view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE."); | ||
434 | m_state &= ~(State.DIRTY); | ||
435 | m_state |= State.SHOWING_CHANGES; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | /// <summary> | ||
440 | /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument. | ||
441 | /// </summary> | ||
442 | protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity( Hashtable sceneList, Scene scene) | ||
443 | { | ||
444 | int somethingAddedToList = 1; | ||
445 | System.Collections.Generic.List<Scene> newList = new List<Scene>(); | ||
446 | newList.Add(scene); | ||
447 | |||
448 | if (! sceneList.ContainsValue(scene)) | ||
449 | { | ||
450 | foreach(Object sceneObj in sceneList) | ||
451 | newList.Add((Scene) sceneObj); | ||
452 | return newList; | ||
453 | } | ||
454 | |||
455 | while(somethingAddedToList > 0) | ||
456 | { | ||
457 | somethingAddedToList = 0; | ||
458 | for(int i = 0; i < newList.Count; i++) | ||
459 | { | ||
460 | foreach(Object sceneObj in sceneList.Values) | ||
461 | { | ||
462 | if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (! newList.Contains((Scene)sceneObj)) ) | ||
463 | { | ||
464 | newList.Add((Scene)sceneObj); | ||
465 | somethingAddedToList++; | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | } | ||
470 | |||
471 | foreach(Object sceneObj in sceneList.Values) | ||
472 | if (! newList.Contains((Scene)sceneObj)) | ||
473 | newList.Add((Scene)sceneObj); | ||
474 | |||
475 | return newList; | ||
476 | } | ||
477 | |||
478 | /// <summary> | ||
479 | /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned. | ||
480 | /// </summary> | ||
481 | private SceneObjectGroup GetGroupByPrim(uint localID) | ||
482 | { | ||
483 | foreach(Object currScene in m_sceneList.Values) | ||
484 | { | ||
485 | foreach (EntityBase ent in ((Scene)currScene).GetEntities()) | ||
486 | { | ||
487 | if (ent is SceneObjectGroup) | ||
488 | { | ||
489 | if (((SceneObjectGroup)ent).HasChildPrim(localID)) | ||
490 | return (SceneObjectGroup)ent; | ||
491 | } | ||
492 | } | ||
493 | } | ||
494 | return null; | 118 | return null; |
495 | } | 119 | } |
496 | //------------------------------------------------ EVENTS ----------------------------------------------------// | 120 | |
497 | 121 | private void Initialize(CMModel model, CMView view, Scene scene, int channel) | |
498 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) | 122 | { |
499 | { | 123 | lock(this) |
500 | } | 124 | { |
501 | 125 | m_estateModule = scene.RequestModuleInterface<IEstateModule>(); | |
502 | /// <summary> | 126 | m_thread = new Thread( MainLoop ); |
503 | /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions. | 127 | m_thread.Name = "Content Management"; |
504 | /// </summary> | 128 | m_thread.IsBackground = true; |
505 | protected void StartManaging(IClientAPI client) | 129 | m_thread.Start(); |
506 | { | 130 | ThreadTracker.Add(m_thread); |
507 | m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services."); | 131 | m_state = State.NONE; |
508 | client.OnChatFromViewer += SimChatSent; | 132 | } |
509 | init = true; | 133 | } |
510 | 134 | ||
511 | OnNewClient(client); | 135 | /// <summary> |
512 | 136 | /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions. | |
513 | m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client."); | 137 | /// </summary> |
514 | client.OnUpdatePrimScale += UpdateSingleScale; | 138 | private void MainLoop() |
139 | { | ||
140 | CMModel model = m_model; CMView view = m_view; int channel = m_channel; | ||
141 | Work currentJob = new Work(); | ||
142 | while(true) | ||
143 | { | ||
144 | currentJob = m_WorkQueue.Dequeue(); | ||
145 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request"); | ||
146 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type); | ||
147 | switch(currentJob.Type) | ||
148 | { | ||
149 | case WorkType.NONE: | ||
150 | break; | ||
151 | case WorkType.OBJECTATTRIBUTECHANGE: | ||
152 | ObjectAttributeChanged(model, view, currentJob.LocalId); | ||
153 | break; | ||
154 | case WorkType.PRIMITIVEADDED: | ||
155 | PrimitiveAdded(model, view, currentJob); | ||
156 | break; | ||
157 | case WorkType.OBJECTDUPLICATED: | ||
158 | ObjectDuplicated(model, view, currentJob.LocalId); | ||
159 | break; | ||
160 | case WorkType.OBJECTKILLED: | ||
161 | ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1); | ||
162 | break; | ||
163 | case WorkType.UNDODID: | ||
164 | UndoDid(model, view, currentJob.UUID); | ||
165 | break; | ||
166 | case WorkType.NEWCLIENT: | ||
167 | NewClient(view, (IClientAPI) currentJob.Data1); | ||
168 | break; | ||
169 | case WorkType.SIMCHAT: | ||
170 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message); | ||
171 | SimChat(model, view, (OSChatMessage) currentJob.Data1, channel); | ||
172 | break; | ||
173 | default: | ||
174 | m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?"); | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /// <summary> | ||
181 | /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled. | ||
182 | /// </summary> | ||
183 | private void NewClient(CMView view, IClientAPI client) | ||
184 | { | ||
185 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
186 | view.SendMetaEntitiesToNewClient(client); | ||
187 | } | ||
188 | |||
189 | /// <summary> | ||
190 | /// Only called by the MainLoop. | ||
191 | /// </summary> | ||
192 | private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId) | ||
193 | { | ||
194 | SceneObjectGroup group = null; | ||
195 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
196 | { | ||
197 | group = GetGroupByPrim(LocalId); | ||
198 | if (group != null) | ||
199 | { | ||
200 | view.DisplayAuras( model.UpdateNormalEntityEffects(group) ); //Might be a normal entity (green aura) | ||
201 | m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura) | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /// <summary> | ||
207 | /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied. | ||
208 | /// </summary> | ||
209 | private void ObjectDuplicated(CMModel model, CMView view, uint localId) | ||
210 | { | ||
211 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
212 | view.DisplayAuras(model.CheckForNewEntitiesMissingAuras( GetGroupByPrim(localId).Scene )); | ||
213 | } | ||
214 | |||
215 | /// <summary> | ||
216 | /// Only called by the MainLoop. | ||
217 | /// </summary> | ||
218 | private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group) | ||
219 | { | ||
220 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
221 | { | ||
222 | view.RemoveOrUpdateDeletedEntity(group); | ||
223 | model.RemoveOrUpdateDeletedEntity(group); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | /// <summary> | ||
228 | /// Only called by the MainLoop. | ||
229 | /// </summary> | ||
230 | private void PrimitiveAdded(CMModel model, CMView view, Work currentJob) | ||
231 | { | ||
232 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
233 | { | ||
234 | foreach(Object scene in m_sceneList.Values) | ||
235 | m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene)); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | /// <summary> | ||
240 | /// Only called by the MainLoop. | ||
241 | /// </summary> | ||
242 | private void UndoDid(CMModel model, CMView view, LLUUID uuid) | ||
243 | { | ||
244 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
245 | { | ||
246 | ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid); | ||
247 | if (ent != null) | ||
248 | view.DisplayEntity(ent); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | #endregion Private Methods | ||
253 | |||
254 | #region Protected Methods | ||
255 | |||
256 | protected void GroupBeingDeleted(SceneObjectGroup group) | ||
257 | { | ||
258 | m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!"); | ||
259 | Work moreWork = new Work(); | ||
260 | moreWork.Type = WorkType.OBJECTKILLED; | ||
261 | moreWork.Data1 = group.Copy(); | ||
262 | m_WorkQueue.Enqueue(moreWork); | ||
263 | } | ||
264 | |||
265 | protected void ObjectDuplicated(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID) | ||
266 | { | ||
267 | Work moreWork = new Work(); | ||
268 | moreWork.Type = WorkType.OBJECTDUPLICATED; | ||
269 | moreWork.LocalId = localID; | ||
270 | m_WorkQueue.Enqueue(moreWork); | ||
271 | m_log.Debug("[CONTENT MANAGEMENT] dup queue"); | ||
272 | } | ||
273 | |||
274 | protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID, | ||
275 | LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart, | ||
276 | bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) | ||
277 | { | ||
278 | Work moreWork = new Work(); | ||
279 | moreWork.Type = WorkType.OBJECTDUPLICATED; | ||
280 | moreWork.LocalId = localID; | ||
281 | m_WorkQueue.Enqueue(moreWork); | ||
282 | m_log.Debug("[CONTENT MANAGEMENT] dup queue"); | ||
283 | } | ||
284 | |||
285 | protected void OnNewClient(IClientAPI client) | ||
286 | { | ||
287 | Work moreWork = new Work(); | ||
288 | moreWork.Type = WorkType.NEWCLIENT; | ||
289 | moreWork.Data1 = client; | ||
290 | m_WorkQueue.Enqueue(moreWork); | ||
291 | m_log.Debug("[CONTENT MANAGEMENT] new client"); | ||
292 | } | ||
293 | |||
294 | protected void OnUnDid(IClientAPI remoteClient, LLUUID primId) | ||
295 | { | ||
296 | Work moreWork = new Work(); | ||
297 | moreWork.Type = WorkType.UNDODID; | ||
298 | moreWork.UUID = primId; | ||
299 | m_WorkQueue.Enqueue(moreWork); | ||
300 | m_log.Debug("[CONTENT MANAGEMENT] undid"); | ||
301 | } | ||
302 | |||
303 | /// <summary> | ||
304 | /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument. | ||
305 | /// </summary> | ||
306 | protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity( Hashtable sceneList, Scene scene) | ||
307 | { | ||
308 | int somethingAddedToList = 1; | ||
309 | System.Collections.Generic.List<Scene> newList = new List<Scene>(); | ||
310 | newList.Add(scene); | ||
311 | |||
312 | if (! sceneList.ContainsValue(scene)) | ||
313 | { | ||
314 | foreach(Object sceneObj in sceneList) | ||
315 | newList.Add((Scene) sceneObj); | ||
316 | return newList; | ||
317 | } | ||
318 | |||
319 | while(somethingAddedToList > 0) | ||
320 | { | ||
321 | somethingAddedToList = 0; | ||
322 | for(int i = 0; i < newList.Count; i++) | ||
323 | { | ||
324 | foreach(Object sceneObj in sceneList.Values) | ||
325 | { | ||
326 | if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (! newList.Contains((Scene)sceneObj)) ) | ||
327 | { | ||
328 | newList.Add((Scene)sceneObj); | ||
329 | somethingAddedToList++; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | foreach(Object sceneObj in sceneList.Values) | ||
336 | if (! newList.Contains((Scene)sceneObj)) | ||
337 | newList.Add((Scene)sceneObj); | ||
338 | |||
339 | return newList; | ||
340 | } | ||
341 | |||
342 | //This is stupid, the same information is contained in the first and second argument | ||
343 | protected void SimChatSent(Object x, OSChatMessage e) | ||
344 | { | ||
345 | m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!"); | ||
346 | m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message); | ||
347 | Work moreWork = new Work(); | ||
348 | moreWork.Type = WorkType.SIMCHAT; | ||
349 | moreWork.Data1 = e; | ||
350 | m_WorkQueue.Enqueue(moreWork); | ||
351 | } | ||
352 | |||
353 | /// <summary> | ||
354 | /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions. | ||
355 | /// </summary> | ||
356 | protected void StartManaging(IClientAPI client) | ||
357 | { | ||
358 | m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services."); | ||
359 | client.OnChatFromViewer += SimChatSent; | ||
360 | init = true; | ||
361 | |||
362 | OnNewClient(client); | ||
363 | |||
364 | m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client."); | ||
365 | client.OnUpdatePrimScale += UpdateSingleScale; | ||
515 | client.OnUpdatePrimGroupScale += UpdateMultipleScale; | 366 | client.OnUpdatePrimGroupScale += UpdateMultipleScale; |
516 | client.OnUpdatePrimGroupPosition += UpdateMultiplePosition; | 367 | client.OnUpdatePrimGroupPosition += UpdateMultiplePosition; |
517 | client.OnUpdatePrimSinglePosition += UpdateSinglePosition; | 368 | client.OnUpdatePrimSinglePosition += UpdateSinglePosition; |
518 | client.OnUpdatePrimGroupRotation += UpdateMultipleRotation; | 369 | client.OnUpdatePrimGroupRotation += UpdateMultipleRotation; |
519 | client.OnUpdatePrimSingleRotation += UpdateSingleRotation; | 370 | client.OnUpdatePrimSingleRotation += UpdateSingleRotation; |
520 | client.OnAddPrim += UpdateNewParts; | 371 | client.OnAddPrim += UpdateNewParts; |
521 | client.OnObjectDuplicate += ObjectDuplicated; | 372 | client.OnObjectDuplicate += ObjectDuplicated; |
522 | client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay; | 373 | client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay; |
523 | client.OnUndo += OnUnDid; | 374 | client.OnUndo += OnUnDid; |
524 | //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; | 375 | //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; |
525 | } | 376 | } |
526 | 377 | ||
527 | /// <summary> | 378 | /// <summary> |
528 | /// | 379 | /// |
529 | /// </summary> | 380 | /// </summary> |
530 | protected void StopManaging(LLUUID clientUUID) | 381 | protected void StopManaging(LLUUID clientUUID) |
531 | { | 382 | { |
532 | foreach(Object sceneobj in m_sceneList.Values) | 383 | foreach(Object sceneobj in m_sceneList.Values) |
533 | { | 384 | { |
534 | ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID); | 385 | ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID); |
535 | if (presence != null) | 386 | if (presence != null) |
536 | { | 387 | { |
537 | IClientAPI client = presence.ControllingClient; | 388 | IClientAPI client = presence.ControllingClient; |
538 | m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services."); | 389 | m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services."); |
539 | client.OnChatFromViewer -= SimChatSent; | 390 | client.OnChatFromViewer -= SimChatSent; |
540 | 391 | ||
541 | m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client"); | 392 | m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client"); |
542 | client.OnUpdatePrimScale -= UpdateSingleScale; | 393 | client.OnUpdatePrimScale -= UpdateSingleScale; |
543 | client.OnUpdatePrimGroupScale -= UpdateMultipleScale; | 394 | client.OnUpdatePrimGroupScale -= UpdateMultipleScale; |
544 | client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition; | 395 | client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition; |
545 | client.OnUpdatePrimSinglePosition -= UpdateSinglePosition; | 396 | client.OnUpdatePrimSinglePosition -= UpdateSinglePosition; |
546 | client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation; | 397 | client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation; |
547 | client.OnUpdatePrimSingleRotation -= UpdateSingleRotation; | 398 | client.OnUpdatePrimSingleRotation -= UpdateSingleRotation; |
548 | client.OnAddPrim -= UpdateNewParts; | 399 | client.OnAddPrim -= UpdateNewParts; |
549 | client.OnObjectDuplicate -= ObjectDuplicated; | 400 | client.OnObjectDuplicate -= ObjectDuplicated; |
550 | client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay; | 401 | client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay; |
551 | client.OnUndo -= OnUnDid; | 402 | client.OnUndo -= OnUnDid; |
552 | //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; | 403 | //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; |
553 | return; | 404 | return; |
554 | } | 405 | } |
555 | } | 406 | } |
556 | } | 407 | } |
557 | 408 | ||
558 | protected void GroupBeingDeleted(SceneObjectGroup group) | 409 | protected void UpdateMultiplePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) |
559 | { | 410 | { |
560 | m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!"); | 411 | Work moreWork = new Work(); |
561 | Work moreWork = new Work(); | 412 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; |
562 | moreWork.Type = WorkType.OBJECTKILLED; | 413 | moreWork.LocalId = localID; |
563 | moreWork.Data1 = group.Copy(); | 414 | m_WorkQueue.Enqueue(moreWork); |
564 | m_WorkQueue.Enqueue(moreWork); | 415 | m_log.Debug("[CONTENT MANAGEMENT] pos"); |
565 | } | 416 | } |
566 | 417 | ||
567 | //This is stupid, the same information is contained in the first and second argument | 418 | protected void UpdateMultipleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) |
568 | protected void SimChatSent(Object x, OSChatMessage e) | 419 | { |
569 | { | 420 | Work moreWork = new Work(); |
570 | m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!"); | 421 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; |
571 | m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message); | 422 | moreWork.LocalId = localID; |
572 | Work moreWork = new Work(); | 423 | m_WorkQueue.Enqueue(moreWork); |
573 | moreWork.Type = WorkType.SIMCHAT; | 424 | m_log.Debug("[CONTENT MANAGEMENT] rot"); |
574 | moreWork.Data1 = e; | 425 | } |
575 | m_WorkQueue.Enqueue(moreWork); | 426 | |
576 | } | 427 | protected void UpdateMultipleScale(uint localID, LLVector3 scale, IClientAPI remoteClient) |
577 | 428 | { | |
578 | protected void ObjectDuplicated(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID) | 429 | Work moreWork = new Work(); |
579 | { | 430 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; |
580 | Work moreWork = new Work(); | 431 | moreWork.LocalId = localID; |
581 | moreWork.Type = WorkType.OBJECTDUPLICATED; | 432 | m_WorkQueue.Enqueue(moreWork); |
582 | moreWork.LocalId = localID; | 433 | m_log.Debug("[CONTENT MANAGEMENT]scale"); |
583 | m_WorkQueue.Enqueue(moreWork); | 434 | } |
584 | m_log.Debug("[CONTENT MANAGEMENT] dup queue"); | 435 | |
585 | } | 436 | protected void UpdateNewParts(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape, |
586 | 437 | byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID, | |
587 | protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID, | 438 | byte RayEndIsIntersection) |
588 | LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart, | 439 | { |
589 | bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) | 440 | Work moreWork = new Work(); |
590 | { | 441 | moreWork.Type = WorkType.PRIMITIVEADDED; |
591 | Work moreWork = new Work(); | 442 | moreWork.UUID = ownerID; |
592 | moreWork.Type = WorkType.OBJECTDUPLICATED; | 443 | m_WorkQueue.Enqueue(moreWork); |
593 | moreWork.LocalId = localID; | 444 | m_log.Debug("[CONTENT MANAGEMENT] new parts"); |
594 | m_WorkQueue.Enqueue(moreWork); | 445 | } |
595 | m_log.Debug("[CONTENT MANAGEMENT] dup queue"); | 446 | |
596 | } | 447 | protected void UpdateSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) |
597 | 448 | { | |
598 | protected void OnNewClient(IClientAPI client) | 449 | Work moreWork = new Work(); |
599 | { | 450 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; |
600 | Work moreWork = new Work(); | 451 | moreWork.LocalId = localID; |
601 | moreWork.Type = WorkType.NEWCLIENT; | 452 | m_WorkQueue.Enqueue(moreWork); |
602 | moreWork.Data1 = client; | 453 | m_log.Debug("[CONTENT MANAGEMENT] move"); |
603 | m_WorkQueue.Enqueue(moreWork); | 454 | } |
604 | m_log.Debug("[CONTENT MANAGEMENT] new client"); | 455 | |
605 | } | 456 | /// <summary> |
606 | 457 | /// | |
607 | protected void OnUnDid(IClientAPI remoteClient, LLUUID primId) | 458 | /// </summary> |
608 | { | 459 | protected void UpdateSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) |
609 | Work moreWork = new Work(); | 460 | { |
610 | moreWork.Type = WorkType.UNDODID; | 461 | Work moreWork = new Work(); |
611 | moreWork.UUID = primId; | 462 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; |
612 | m_WorkQueue.Enqueue(moreWork); | 463 | moreWork.LocalId = localID; |
613 | m_log.Debug("[CONTENT MANAGEMENT] undid"); | 464 | m_WorkQueue.Enqueue(moreWork); |
614 | } | 465 | m_log.Debug("[CONTENT MANAGEMENT] rot"); |
615 | 466 | } | |
616 | protected void UpdateSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) | 467 | |
617 | { | 468 | protected void UpdateSingleScale(uint localID, LLVector3 scale, IClientAPI remoteClient) |
618 | Work moreWork = new Work(); | 469 | { |
619 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; | 470 | Work moreWork = new Work(); |
620 | moreWork.LocalId = localID; | 471 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; |
621 | m_WorkQueue.Enqueue(moreWork); | 472 | moreWork.LocalId = localID; |
622 | m_log.Debug("[CONTENT MANAGEMENT] move"); | 473 | m_WorkQueue.Enqueue(moreWork); |
623 | } | 474 | m_log.Debug("[CONTENT MANAGEMENT] scale"); |
624 | 475 | } | |
625 | /// <summary> | 476 | |
626 | /// | 477 | /// <summary> |
627 | /// </summary> | 478 | /// Only called from within the SimChat method. |
628 | protected void UpdateSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) | 479 | /// </summary> |
629 | { | 480 | protected void commit(string message, Scene scene, CMModel model, CMView view) |
630 | Work moreWork = new Work(); | 481 | { |
631 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; | 482 | System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene); |
632 | moreWork.LocalId = localID; | 483 | |
633 | m_WorkQueue.Enqueue(moreWork); | 484 | string[] args = message.Split(new char[] {' '}); |
634 | m_log.Debug("[CONTENT MANAGEMENT] rot"); | 485 | |
635 | } | 486 | char[] logMessage = {' '}; |
636 | 487 | if (args.Length > 1) | |
637 | protected void UpdateSingleScale(uint localID, LLVector3 scale, IClientAPI remoteClient) | 488 | { |
638 | { | 489 | logMessage = new char[message.Length - (args[0].Length)]; |
639 | Work moreWork = new Work(); | 490 | message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length)); |
640 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; | 491 | } |
641 | moreWork.LocalId = localID; | 492 | |
642 | m_WorkQueue.Enqueue(moreWork); | 493 | m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region."); |
643 | m_log.Debug("[CONTENT MANAGEMENT] scale"); | 494 | foreach(Scene currScene in proximitySceneList) |
644 | } | 495 | { |
645 | 496 | model.CommitRegion(currScene, new String(logMessage)); | |
646 | protected void UpdateMultiplePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) | 497 | view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName); |
647 | { | 498 | } |
648 | Work moreWork = new Work(); | 499 | |
649 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; | 500 | view.SendSimChatMessage(scene, "Successfully saved all regions."); |
650 | moreWork.LocalId = localID; | 501 | m_state |= State.DIRTY; |
651 | m_WorkQueue.Enqueue(moreWork); | 502 | |
652 | m_log.Debug("[CONTENT MANAGEMENT] pos"); | 503 | if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES |
653 | } | 504 | { |
654 | 505 | view.SendSimChatMessage(scene, "Updating differences between new revision and current environment."); | |
655 | protected void UpdateMultipleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) | 506 | //Hide objects from users and Forget about them |
656 | { | 507 | view.HideAllMetaEntities(); |
657 | Work moreWork = new Work(); | 508 | view.HideAllAuras(); |
658 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; | 509 | model.DeleteAllMetaObjects(); |
659 | moreWork.LocalId = localID; | 510 | |
660 | m_WorkQueue.Enqueue(moreWork); | 511 | //Recreate them from backend files |
661 | m_log.Debug("[CONTENT MANAGEMENT] rot"); | 512 | foreach(Scene currScene in proximitySceneList) |
662 | } | 513 | { |
663 | 514 | model.UpdateCMEntities(currScene); | |
664 | protected void UpdateMultipleScale(uint localID, LLVector3 scale, IClientAPI remoteClient) | 515 | view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName); |
665 | { | 516 | } |
666 | Work moreWork = new Work(); | 517 | |
667 | moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; | 518 | //Display new objects to users1 |
668 | moreWork.LocalId = localID; | 519 | view.DisplayRecentChanges(); |
669 | m_WorkQueue.Enqueue(moreWork); | 520 | view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE."); |
670 | m_log.Debug("[CONTENT MANAGEMENT]scale"); | 521 | m_state &= ~(State.DIRTY); |
671 | } | 522 | m_state |= State.SHOWING_CHANGES; |
672 | 523 | } | |
673 | protected void UpdateNewParts(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape, | 524 | } |
674 | byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID, | 525 | |
675 | byte RayEndIsIntersection) | 526 | /// <summary> |
676 | { | 527 | /// Only called from within the SimChat method. |
677 | Work moreWork = new Work(); | 528 | /// </summary> |
678 | moreWork.Type = WorkType.PRIMITIVEADDED; | 529 | protected void diffmode(Scene scene, CMModel model, CMView view) |
679 | moreWork.UUID = ownerID; | 530 | { |
680 | m_WorkQueue.Enqueue(moreWork); | 531 | System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene); |
681 | m_log.Debug("[CONTENT MANAGEMENT] new parts"); | 532 | |
682 | } | 533 | if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF |
683 | } | 534 | { |
684 | } | 535 | view.SendSimChatMessage(scene, "Hiding all meta objects."); |
536 | view.HideAllMetaEntities(); | ||
537 | view.HideAllAuras(); | ||
538 | view.SendSimChatMessage(scene, "Diff-mode = OFF"); | ||
539 | |||
540 | m_state &= ~State.SHOWING_CHANGES; | ||
541 | return; | ||
542 | } | ||
543 | else // TURN ON | ||
544 | { | ||
545 | if ((m_state & State.DIRTY) != 0 || m_state == State.NONE) | ||
546 | { | ||
547 | view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision"); | ||
548 | //Hide objects from users and Forget about them | ||
549 | view.HideAllMetaEntities(); | ||
550 | view.HideAllAuras(); | ||
551 | model.DeleteAllMetaObjects(); | ||
552 | //Recreate them from backend files | ||
553 | foreach(Object currScene in m_sceneList.Values) | ||
554 | model.UpdateCMEntities((Scene) currScene); | ||
555 | } | ||
556 | else if ((m_state & State.DIRTY) != 0) { | ||
557 | view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision"); | ||
558 | foreach(Scene currScene in proximitySceneList) | ||
559 | model.UpdateCMEntities(currScene); | ||
560 | } | ||
561 | |||
562 | view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment"); | ||
563 | foreach(Scene currScene in proximitySceneList) | ||
564 | model.CheckForNewEntitiesMissingAuras(currScene); | ||
565 | view.DisplayRecentChanges(); | ||
566 | |||
567 | view.SendSimChatMessage(scene, "Diff-mode = ON"); | ||
568 | m_state |= State.SHOWING_CHANGES; | ||
569 | m_state &= ~State.DIRTY; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | /// <summary> | ||
574 | /// Only called from within the SimChat method. Hides all auras and meta entities, | ||
575 | /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene, | ||
576 | /// then lets the view update the clients of the new objects. | ||
577 | /// </summary> | ||
578 | protected void rollback(Scene scene, CMModel model, CMView view) | ||
579 | { | ||
580 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
581 | { | ||
582 | view.HideAllAuras(); | ||
583 | view.HideAllMetaEntities(); | ||
584 | } | ||
585 | |||
586 | System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene); | ||
587 | foreach(Scene currScene in proximitySceneList) | ||
588 | model.RollbackRegion(currScene); | ||
589 | |||
590 | if ((m_state & State.DIRTY) != 0 ) | ||
591 | { | ||
592 | model.DeleteAllMetaObjects(); | ||
593 | foreach(Scene currScene in proximitySceneList) | ||
594 | model.UpdateCMEntities(currScene); | ||
595 | } | ||
596 | |||
597 | if ((m_state & State.SHOWING_CHANGES) > 0) | ||
598 | view.DisplayRecentChanges(); | ||
599 | } | ||
600 | |||
601 | #endregion Protected Methods | ||
602 | |||
603 | #region Public Methods | ||
604 | |||
605 | /// <summary> | ||
606 | /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene. | ||
607 | /// </summary> | ||
608 | /// <param name="scene"> | ||
609 | /// A <see cref="Scene"/> | ||
610 | /// </param> | ||
611 | public void RegisterNewRegion(Scene scene) | ||
612 | { | ||
613 | m_sceneList.Add(scene.RegionInfo.RegionID, scene); | ||
614 | |||
615 | m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID); | ||
616 | m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System."); | ||
617 | |||
618 | scene.EventManager.OnNewClient += StartManaging; | ||
619 | scene.EventManager.OnRemovePresence += StopManaging; | ||
620 | // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | ||
621 | scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted; | ||
622 | } | ||
623 | |||
624 | /// <summary> | ||
625 | /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command. | ||
626 | /// </summary> | ||
627 | public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel) | ||
628 | { | ||
629 | if (e.Channel != channel) | ||
630 | return; | ||
631 | if (e.Sender == null) | ||
632 | return; | ||
633 | |||
634 | m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message); | ||
635 | |||
636 | IClientAPI client = e.Sender; | ||
637 | Scene scene = (Scene) e.Scene; | ||
638 | string message = e.Message; | ||
639 | string[] args = e.Message.Split(new char[] {' '}); | ||
640 | |||
641 | ScenePresence avatar = scene.GetScenePresence(client.AgentId); | ||
642 | |||
643 | if (!(m_estateModule.IsManager(avatar.UUID))) | ||
644 | { | ||
645 | m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring."); | ||
646 | view.SendSimChatMessage(scene, "You must be an estate manager to perform that action."); | ||
647 | return; | ||
648 | } | ||
649 | |||
650 | switch(args[0]) | ||
651 | { | ||
652 | case "ci": | ||
653 | case "commit": | ||
654 | commit(message, scene, model, view); | ||
655 | break; | ||
656 | case "dm": | ||
657 | case "diff-mode": | ||
658 | diffmode(scene, model, view); | ||
659 | break; | ||
660 | case "rb": | ||
661 | case "rollback": | ||
662 | rollback(scene, model, view); | ||
663 | break; | ||
664 | case "help": | ||
665 | m_view.DisplayHelpMenu(scene); | ||
666 | break; | ||
667 | default: | ||
668 | view.SendSimChatMessage(scene, "Command not found: " + args[0]); | ||
669 | break; | ||
670 | } | ||
671 | } | ||
672 | |||
673 | #endregion Public Methods | ||
674 | |||
675 | #region Other | ||
676 | |||
677 | /// <value> | ||
678 | /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk. | ||
679 | /// </value> | ||
680 | [Flags] | ||
681 | private enum State | ||
682 | { | ||
683 | NONE = 0, | ||
684 | DIRTY = 1, // The meta entities may not correctly represent the last revision. | ||
685 | SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user. | ||
686 | } | ||
687 | |||
688 | /// <value> | ||
689 | /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem. | ||
690 | /// </value> | ||
691 | private struct Work | ||
692 | { | ||
693 | #region Fields | ||
694 | |||
695 | public Object Data1; //Just space for holding data. | ||
696 | public Object Data2; //Just more space for holding data. | ||
697 | public uint LocalId; //Convenient | ||
698 | public WorkType Type; | ||
699 | public LLUUID UUID; //Convenient | ||
700 | |||
701 | #endregion Fields | ||
702 | } | ||
703 | |||
704 | /// <value> | ||
705 | /// Identifies what the data in struct Work should be used for. | ||
706 | /// </value> | ||
707 | private enum WorkType | ||
708 | { | ||
709 | NONE, | ||
710 | OBJECTATTRIBUTECHANGE, | ||
711 | PRIMITIVEADDED, | ||
712 | OBJECTDUPLICATED, | ||
713 | OBJECTKILLED, | ||
714 | UNDODID, | ||
715 | NEWCLIENT, | ||
716 | SIMCHAT | ||
717 | } | ||
718 | |||
719 | #endregion Other | ||
720 | } | ||
721 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs index 9f50e23..2383a6d 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs | |||
@@ -1,148 +1,169 @@ | |||
1 | #region Header | ||
2 | |||
1 | // CMEntityCollection.cs created with MonoDevelop | 3 | // CMEntityCollection.cs created with MonoDevelop |
2 | // User: bongiojp at 10:09 AM 7/7/2008 | 4 | // User: bongiojp at 10:09 AM 7/7/2008 |
3 | // | 5 | // |
4 | // Creates, Deletes, Stores ContentManagementEntities | 6 | // Creates, Deletes, Stores ContentManagementEntities |
5 | // | 7 | // |
6 | 8 | ||
9 | #endregion Header | ||
7 | 10 | ||
8 | using System; | 11 | using System; |
9 | using System.Collections.Generic; | ||
10 | using System.Collections; | 12 | using System.Collections; |
13 | using System.Collections.Generic; | ||
14 | using System.Threading; | ||
15 | |||
11 | using libsecondlife; | 16 | using libsecondlife; |
17 | |||
12 | using Nini.Config; | 18 | using Nini.Config; |
19 | |||
13 | using OpenSim; | 20 | using OpenSim; |
14 | using OpenSim.Framework; | 21 | using OpenSim.Framework; |
15 | using OpenSim.Region.Environment.Interfaces; | 22 | using OpenSim.Region.Environment.Interfaces; |
16 | using OpenSim.Region.Environment.Scenes; | 23 | using OpenSim.Region.Environment.Scenes; |
17 | using log4net; | ||
18 | using OpenSim.Region.Physics.Manager; | 24 | using OpenSim.Region.Physics.Manager; |
25 | |||
26 | using log4net; | ||
27 | |||
19 | using Axiom.Math; | 28 | using Axiom.Math; |
20 | using System.Threading; | ||
21 | 29 | ||
22 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 30 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
23 | { | 31 | { |
24 | 32 | public class CMEntityCollection | |
25 | public class CMEntityCollection | 33 | { |
26 | { | 34 | #region Fields |
27 | // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 35 | |
28 | 36 | // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | |
29 | // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or | 37 | // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or |
30 | // old versions of deleted SceneObjectGroups will be stored in this hash table. | 38 | // old versions of deleted SceneObjectGroups will be stored in this hash table. |
31 | // The LLUUID keys are from the SceneObjectGroup RootPart UUIDs | 39 | // The LLUUID keys are from the SceneObjectGroup RootPart UUIDs |
32 | protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //LLUUID to ContentManagementEntity | 40 | protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //LLUUID to ContentManagementEntity |
33 | 41 | ||
34 | // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable | 42 | // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable |
35 | // The LLUUID keys are from the SceneObjectPart that they are supposed to be on. | 43 | // The LLUUID keys are from the SceneObjectPart that they are supposed to be on. |
36 | protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //LLUUID to AuraMetaEntity | 44 | protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //LLUUID to AuraMetaEntity |
37 | 45 | ||
38 | public Hashtable Entities | 46 | #endregion Fields |
39 | { | 47 | |
40 | get { return m_CMEntityHash; } | 48 | #region Constructors |
41 | } | 49 | |
42 | 50 | public CMEntityCollection() | |
43 | public Hashtable Auras | 51 | { |
44 | { | 52 | } |
45 | get {return m_NewlyCreatedEntityAura; } | 53 | |
46 | } | 54 | #endregion Constructors |
47 | 55 | ||
48 | public CMEntityCollection() | 56 | #region Public Properties |
49 | {} | 57 | |
50 | 58 | public Hashtable Auras | |
51 | public bool AddAura(ContentManagementEntity aura) | 59 | { |
52 | { | 60 | get {return m_NewlyCreatedEntityAura; } |
53 | if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID)) | 61 | } |
54 | return false; | 62 | |
55 | m_NewlyCreatedEntityAura.Add(aura.UUID, aura); | 63 | public Hashtable Entities |
56 | return true; | 64 | { |
57 | } | 65 | get { return m_CMEntityHash; } |
58 | 66 | } | |
59 | public bool AddEntity(ContentManagementEntity ent) | 67 | |
60 | { | 68 | #endregion Public Properties |
61 | if (m_CMEntityHash.ContainsKey(ent.UUID)) | 69 | |
62 | return false; | 70 | #region Public Methods |
63 | m_CMEntityHash.Add(ent.UUID, ent); | 71 | |
64 | return true; | 72 | public bool AddAura(ContentManagementEntity aura) |
65 | } | 73 | { |
66 | 74 | if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID)) | |
67 | public bool RemoveNewlyCreatedEntityAura(LLUUID uuid) | 75 | return false; |
68 | { | 76 | m_NewlyCreatedEntityAura.Add(aura.UUID, aura); |
69 | if (!m_NewlyCreatedEntityAura.ContainsKey(uuid)) | 77 | return true; |
70 | return false; | 78 | } |
71 | m_NewlyCreatedEntityAura.Remove(uuid); | 79 | |
72 | return true; | 80 | public bool AddEntity(ContentManagementEntity ent) |
73 | } | 81 | { |
74 | 82 | if (m_CMEntityHash.ContainsKey(ent.UUID)) | |
75 | public bool RemoveEntity(LLUUID uuid) | 83 | return false; |
76 | { | 84 | m_CMEntityHash.Add(ent.UUID, ent); |
77 | if (!m_CMEntityHash.ContainsKey(uuid)) | 85 | return true; |
78 | return false; | 86 | } |
79 | m_CMEntityHash.Remove(uuid); | 87 | |
80 | return true; | 88 | // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash |
81 | } | 89 | public System.Collections.ArrayList CheckForMissingEntities(System.Collections.Generic.List<EntityBase> currList) |
82 | 90 | { | |
83 | public void ClearAll() | 91 | System.Collections.ArrayList missingList = new System.Collections.ArrayList(); |
84 | { | 92 | SceneObjectGroup temp = null; |
85 | m_CMEntityHash.Clear(); | 93 | foreach( EntityBase currObj in currList ) |
86 | m_NewlyCreatedEntityAura.Clear(); | 94 | { |
87 | } | 95 | if (! (currObj is SceneObjectGroup)) |
88 | 96 | continue; | |
89 | 97 | temp = (SceneObjectGroup) currObj; | |
90 | 98 | ||
91 | // Old uuid and new sceneobjectgroup | 99 | if (m_CMEntityHash.ContainsKey(temp.UUID)) |
92 | public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part) | 100 | { |
93 | { | 101 | foreach(SceneObjectPart part in temp.Children.Values) |
94 | AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene, | 102 | if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) |
95 | part.ParentGroup.Scene.PrimIDAllocate(), | 103 | missingList.Add(part); |
96 | part.GetWorldPosition(), | 104 | } |
97 | MetaEntity.TRANSLUCENT, | 105 | else //Entire group is missing from revision. (and is a new part in region) |
98 | new LLVector3(0,254,0), | 106 | { |
99 | part.Scale | 107 | foreach(SceneObjectPart part in temp.Children.Values) |
100 | ); | 108 | missingList.Add(part); |
101 | m_NewlyCreatedEntityAura.Add(part.UUID, ent); | 109 | } |
102 | return ent; | 110 | } |
103 | } | 111 | return missingList; |
104 | 112 | } | |
105 | // Old uuid and new sceneobjectgroup | 113 | |
106 | public ContentManagementEntity CreateNewEntity(SceneObjectGroup group) | 114 | public void ClearAll() |
107 | { | 115 | { |
108 | ContentManagementEntity ent = new ContentManagementEntity(group, false); | 116 | m_CMEntityHash.Clear(); |
109 | m_CMEntityHash.Add(group.UUID, ent); | 117 | m_NewlyCreatedEntityAura.Clear(); |
110 | return ent; | 118 | } |
111 | } | 119 | |
112 | 120 | // Old uuid and new sceneobjectgroup | |
113 | public ContentManagementEntity CreateNewEntity(String xml, Scene scene) | 121 | public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part) |
114 | { | 122 | { |
115 | ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false); | 123 | AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene, |
116 | if (ent == null) | 124 | part.ParentGroup.Scene.PrimIDAllocate(), |
117 | return null; | 125 | part.GetWorldPosition(), |
118 | m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent); | 126 | MetaEntity.TRANSLUCENT, |
119 | return ent; | 127 | new LLVector3(0,254,0), |
120 | } | 128 | part.Scale |
121 | 129 | ); | |
122 | // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash | 130 | m_NewlyCreatedEntityAura.Add(part.UUID, ent); |
123 | public System.Collections.ArrayList CheckForMissingEntities(System.Collections.Generic.List<EntityBase> currList) | 131 | return ent; |
124 | { | 132 | } |
125 | System.Collections.ArrayList missingList = new System.Collections.ArrayList(); | 133 | |
126 | SceneObjectGroup temp = null; | 134 | // Old uuid and new sceneobjectgroup |
127 | foreach( EntityBase currObj in currList ) | 135 | public ContentManagementEntity CreateNewEntity(SceneObjectGroup group) |
128 | { | 136 | { |
129 | if (! (currObj is SceneObjectGroup)) | 137 | ContentManagementEntity ent = new ContentManagementEntity(group, false); |
130 | continue; | 138 | m_CMEntityHash.Add(group.UUID, ent); |
131 | temp = (SceneObjectGroup) currObj; | 139 | return ent; |
132 | 140 | } | |
133 | if (m_CMEntityHash.ContainsKey(temp.UUID)) | 141 | |
134 | { | 142 | public ContentManagementEntity CreateNewEntity(String xml, Scene scene) |
135 | foreach(SceneObjectPart part in temp.Children.Values) | 143 | { |
136 | if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) | 144 | ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false); |
137 | missingList.Add(part); | 145 | if (ent == null) |
138 | } | 146 | return null; |
139 | else //Entire group is missing from revision. (and is a new part in region) | 147 | m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent); |
140 | { | 148 | return ent; |
141 | foreach(SceneObjectPart part in temp.Children.Values) | 149 | } |
142 | missingList.Add(part); | 150 | |
143 | } | 151 | public bool RemoveEntity(LLUUID uuid) |
144 | } | 152 | { |
145 | return missingList; | 153 | if (!m_CMEntityHash.ContainsKey(uuid)) |
146 | } | 154 | return false; |
147 | } | 155 | m_CMEntityHash.Remove(uuid); |
148 | } | 156 | return true; |
157 | } | ||
158 | |||
159 | public bool RemoveNewlyCreatedEntityAura(LLUUID uuid) | ||
160 | { | ||
161 | if (!m_NewlyCreatedEntityAura.ContainsKey(uuid)) | ||
162 | return false; | ||
163 | m_NewlyCreatedEntityAura.Remove(uuid); | ||
164 | return true; | ||
165 | } | ||
166 | |||
167 | #endregion Public Methods | ||
168 | } | ||
169 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs index a47f83a..3355fa3 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs | |||
@@ -1,47 +1,128 @@ | |||
1 | #region Header | ||
2 | |||
1 | // CMModel.cs | 3 | // CMModel.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | // | 5 | // |
4 | // | 6 | // |
5 | 7 | ||
8 | #endregion Header | ||
9 | |||
6 | using System; | 10 | using System; |
7 | using System.Collections.Generic; | ||
8 | using System.Collections; | 11 | using System.Collections; |
12 | using System.Collections.Generic; | ||
13 | using System.Diagnostics; | ||
14 | |||
9 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
10 | using OpenSim; | 17 | using OpenSim; |
11 | using OpenSim.Framework; | 18 | using OpenSim.Framework; |
12 | using OpenSim.Region.Environment.Interfaces; | 19 | using OpenSim.Region.Environment.Interfaces; |
13 | using OpenSim.Region.Environment.Scenes; | 20 | using OpenSim.Region.Environment.Scenes; |
14 | using log4net; | ||
15 | using OpenSim.Region.Physics.Manager; | 21 | using OpenSim.Region.Physics.Manager; |
22 | |||
23 | using log4net; | ||
24 | |||
16 | using Axiom.Math; | 25 | using Axiom.Math; |
17 | using System.Diagnostics; | ||
18 | 26 | ||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 27 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
20 | { | 28 | { |
21 | |||
22 | public class CMModel | 29 | public class CMModel |
23 | { | 30 | { |
31 | #region Static Fields | ||
32 | |||
24 | static float TimeToUpdate = 0; | 33 | static float TimeToUpdate = 0; |
25 | static float TimeToConvertXml = 0; | 34 | static float TimeToConvertXml = 0; |
26 | |||
27 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 35 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
28 | 36 | ||
29 | IContentDatabase m_database = null; | 37 | #endregion Static Fields |
30 | 38 | ||
39 | #region Fields | ||
40 | |||
31 | /// <value> | 41 | /// <value> |
32 | /// The class that contains all auras and metaentities used in the CMS. | 42 | /// The class that contains all auras and metaentities used in the CMS. |
33 | /// </value> | 43 | /// </value> |
34 | CMEntityCollection m_MetaEntityCollection = new CMEntityCollection(); | 44 | CMEntityCollection m_MetaEntityCollection = new CMEntityCollection(); |
35 | 45 | IContentDatabase m_database = null; | |
46 | |||
47 | #endregion Fields | ||
48 | |||
49 | #region Constructors | ||
50 | |||
51 | public CMModel() | ||
52 | { | ||
53 | } | ||
54 | |||
55 | #endregion Constructors | ||
56 | |||
57 | #region Public Properties | ||
58 | |||
36 | public CMEntityCollection MetaEntityCollection | 59 | public CMEntityCollection MetaEntityCollection |
37 | { | 60 | { |
38 | get { return m_MetaEntityCollection; } | 61 | get { return m_MetaEntityCollection; } |
39 | } | 62 | } |
40 | 63 | ||
41 | public CMModel() | 64 | #endregion Public Properties |
65 | |||
66 | #region Public Methods | ||
67 | |||
68 | /// <summary> | ||
69 | /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity | ||
70 | /// it is a new part that must have a green aura (for diff mode). | ||
71 | /// Returns list of ContentManagementEntities | ||
72 | /// </summary> | ||
73 | public ArrayList CheckForNewEntitiesMissingAuras(Scene scene) | ||
74 | { | ||
75 | ArrayList missingList = null; | ||
76 | ArrayList newList = new ArrayList(); | ||
77 | |||
78 | m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName); | ||
79 | |||
80 | //Check if the current scene has groups not included in the current list of MetaEntities | ||
81 | //If so, then the current scene's parts that are new should be marked green. | ||
82 | missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities()); | ||
83 | |||
84 | foreach(Object missingPart in missingList) | ||
85 | { | ||
86 | if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID)) | ||
87 | continue; | ||
88 | newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart)); | ||
89 | } | ||
90 | m_log.Info("Number of missing objects found: " + newList.Count); | ||
91 | return newList; | ||
92 | } | ||
93 | |||
94 | /// <summary> | ||
95 | /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message. | ||
96 | /// </summary> | ||
97 | public void CommitRegion(Scene scene, String logMessage) | ||
42 | { | 98 | { |
99 | m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length); | ||
100 | m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage); | ||
101 | m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName ); | ||
43 | } | 102 | } |
44 | 103 | ||
104 | public void DeleteAllMetaObjects() | ||
105 | { | ||
106 | m_MetaEntityCollection.ClearAll(); | ||
107 | } | ||
108 | |||
109 | public ContentManagementEntity FindMetaEntityAffectedByUndo(LLUUID uuid) | ||
110 | { | ||
111 | ContentManagementEntity ent = GetMetaGroupByPrim(uuid); | ||
112 | return ent; | ||
113 | } | ||
114 | |||
115 | //-------------------------------- HELPERS --------------------------------------------------------------------// | ||
116 | public ContentManagementEntity GetMetaGroupByPrim(LLUUID uuid) | ||
117 | { | ||
118 | foreach (Object ent in m_MetaEntityCollection.Entities.Values) | ||
119 | { | ||
120 | if (((ContentManagementEntity)ent).HasChildPrim(uuid)) | ||
121 | return (ContentManagementEntity)ent; | ||
122 | } | ||
123 | return null; | ||
124 | } | ||
125 | |||
45 | public void Initialise(string database) | 126 | public void Initialise(string database) |
46 | { | 127 | { |
47 | if (database == "FileSystemDatabase") | 128 | if (database == "FileSystemDatabase") |
@@ -49,12 +130,12 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
49 | else if (database == "GitDatabase") | 130 | else if (database == "GitDatabase") |
50 | m_database = new GitDatabase(); | 131 | m_database = new GitDatabase(); |
51 | } | 132 | } |
52 | 133 | ||
53 | public void InitialiseDatabase(Scene scene, string dir) | 134 | public void InitialiseDatabase(Scene scene, string dir) |
54 | { | 135 | { |
55 | m_database.Initialise(scene, dir); | 136 | m_database.Initialise(scene, dir); |
56 | } | 137 | } |
57 | 138 | ||
58 | /// <summary> | 139 | /// <summary> |
59 | /// Should be called just once to finish initializing the database. | 140 | /// Should be called just once to finish initializing the database. |
60 | /// </summary> | 141 | /// </summary> |
@@ -62,13 +143,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
62 | { | 143 | { |
63 | m_database.PostInitialise(); | 144 | m_database.PostInitialise(); |
64 | } | 145 | } |
65 | 146 | ||
66 | public ContentManagementEntity FindMetaEntityAffectedByUndo(LLUUID uuid) | ||
67 | { | ||
68 | ContentManagementEntity ent = GetMetaGroupByPrim(uuid); | ||
69 | return ent; | ||
70 | } | ||
71 | |||
72 | /// <summary> | 147 | /// <summary> |
73 | /// Removes the green aura when an a new scene object group is deleted. | 148 | /// Removes the green aura when an a new scene object group is deleted. |
74 | /// </summary> | 149 | /// </summary> |
@@ -79,17 +154,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
79 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 154 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) |
80 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); | 155 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); |
81 | } | 156 | } |
82 | 157 | ||
83 | /// <summary> | ||
84 | /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message. | ||
85 | /// </summary> | ||
86 | public void CommitRegion(Scene scene, String logMessage) | ||
87 | { | ||
88 | m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length); | ||
89 | m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage); | ||
90 | m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName ); | ||
91 | } | ||
92 | |||
93 | /// <summary> | 158 | /// <summary> |
94 | /// Retrieves the latest revision of a region in xml form, | 159 | /// Retrieves the latest revision of a region in xml form, |
95 | /// converts it to scene object groups and scene presences, | 160 | /// converts it to scene object groups and scene presences, |
@@ -105,20 +170,20 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
105 | Dictionary<LLUUID, EntityBase> ReplacementList = new Dictionary<LLUUID,EntityBase>(); | 170 | Dictionary<LLUUID, EntityBase> ReplacementList = new Dictionary<LLUUID,EntityBase>(); |
106 | int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID); | 171 | int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID); |
107 | EntityBase[] searchArray; | 172 | EntityBase[] searchArray; |
108 | 173 | ||
109 | xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision); | 174 | xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision); |
110 | if (xmllist == null) | 175 | if (xmllist == null) |
111 | { | 176 | { |
112 | m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ")."); | 177 | m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ")."); |
113 | return; | 178 | return; |
114 | } | 179 | } |
115 | 180 | ||
116 | m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ")."); | 181 | m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ")."); |
117 | m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count); | 182 | m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count); |
118 | m_log.Info("[CMMODEL]: Converting scene entities list to specified revision."); | 183 | m_log.Info("[CMMODEL]: Converting scene entities list to specified revision."); |
119 | 184 | ||
120 | m_log.ErrorFormat("[CMMODEL]: 1"); | 185 | m_log.ErrorFormat("[CMMODEL]: 1"); |
121 | 186 | ||
122 | foreach (string xml in xmllist) | 187 | foreach (string xml in xmllist) |
123 | { | 188 | { |
124 | try{ | 189 | try{ |
@@ -143,7 +208,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
143 | { | 208 | { |
144 | if (entity == null) | 209 | if (entity == null) |
145 | continue; | 210 | continue; |
146 | 211 | ||
147 | if (entity is ScenePresence) | 212 | if (entity is ScenePresence) |
148 | { | 213 | { |
149 | ReplacementList.Add(entity.UUID, entity); | 214 | ReplacementList.Add(entity.UUID, entity); |
@@ -162,7 +227,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
162 | } | 227 | } |
163 | break; | 228 | break; |
164 | } | 229 | } |
165 | 230 | ||
166 | foreach(LLUUID uuid in deleteListUUIDs.Keys) | 231 | foreach(LLUUID uuid in deleteListUUIDs.Keys) |
167 | { | 232 | { |
168 | try | 233 | try |
@@ -179,7 +244,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
179 | m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e); | 244 | m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e); |
180 | } | 245 | } |
181 | } | 246 | } |
182 | 247 | ||
183 | lock (scene) | 248 | lock (scene) |
184 | { | 249 | { |
185 | scene.Entities = ReplacementList; | 250 | scene.Entities = ReplacementList; |
@@ -191,7 +256,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
191 | { | 256 | { |
192 | if (!(ent is SceneObjectGroup)) | 257 | if (!(ent is SceneObjectGroup)) |
193 | continue; | 258 | continue; |
194 | 259 | ||
195 | if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) LLObject.ObjectFlags.Phantom) == 0) | 260 | if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) LLObject.ObjectFlags.Phantom) == 0) |
196 | ((SceneObjectGroup)ent).ApplyPhysics(true); | 261 | ((SceneObjectGroup)ent).ApplyPhysics(true); |
197 | ((SceneObjectGroup)ent).AttachToBackup(); | 262 | ((SceneObjectGroup)ent).AttachToBackup(); |
@@ -206,32 +271,6 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
206 | m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup."); | 271 | m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup."); |
207 | scene.Backup(); | 272 | scene.Backup(); |
208 | } | 273 | } |
209 | |||
210 | /// <summary> | ||
211 | /// Detects if a scene object group from the scene list has moved or changed scale. The green aura | ||
212 | /// that surrounds the object is then moved or scaled with the group. | ||
213 | /// </summary> | ||
214 | public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group) | ||
215 | { | ||
216 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); | ||
217 | if (group == null) | ||
218 | return null; | ||
219 | foreach(SceneObjectPart part in group.Children.Values) | ||
220 | { | ||
221 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
222 | { | ||
223 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new LLVector3(0,254,0), part.Scale); | ||
224 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); | ||
225 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); | ||
226 | } | ||
227 | } | ||
228 | return auraList; | ||
229 | } | ||
230 | |||
231 | public void DeleteAllMetaObjects() | ||
232 | { | ||
233 | m_MetaEntityCollection.ClearAll(); | ||
234 | } | ||
235 | 274 | ||
236 | /// <summary> | 275 | /// <summary> |
237 | /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences | 276 | /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences |
@@ -257,53 +296,37 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
257 | TimeToConvertXml += y.ElapsedMilliseconds; | 296 | TimeToConvertXml += y.ElapsedMilliseconds; |
258 | m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds); | 297 | m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds); |
259 | m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml); | 298 | m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml); |
260 | 299 | ||
261 | m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras"); | 300 | m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras"); |
262 | CheckForNewEntitiesMissingAuras(scene); | 301 | CheckForNewEntitiesMissingAuras(scene); |
263 | 302 | ||
264 | x.Stop(); | 303 | x.Stop(); |
265 | TimeToUpdate += x.ElapsedMilliseconds; | 304 | TimeToUpdate += x.ElapsedMilliseconds; |
266 | m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds); | 305 | m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds); |
267 | m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate); | 306 | m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate); |
268 | |||
269 | } | 307 | } |
270 | 308 | ||
271 | /// <summary> | 309 | /// <summary> |
272 | /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity | 310 | /// Detects if a scene object group from the scene list has moved or changed scale. The green aura |
273 | /// it is a new part that must have a green aura (for diff mode). | 311 | /// that surrounds the object is then moved or scaled with the group. |
274 | /// Returns list of ContentManagementEntities | ||
275 | /// </summary> | 312 | /// </summary> |
276 | public ArrayList CheckForNewEntitiesMissingAuras(Scene scene) | 313 | public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group) |
277 | { | ||
278 | ArrayList missingList = null; | ||
279 | ArrayList newList = new ArrayList(); | ||
280 | |||
281 | m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName); | ||
282 | |||
283 | //Check if the current scene has groups not included in the current list of MetaEntities | ||
284 | //If so, then the current scene's parts that are new should be marked green. | ||
285 | missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities()); | ||
286 | |||
287 | foreach(Object missingPart in missingList) | ||
288 | { | ||
289 | if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID)) | ||
290 | continue; | ||
291 | newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart)); | ||
292 | } | ||
293 | m_log.Info("Number of missing objects found: " + newList.Count); | ||
294 | return newList; | ||
295 | } | ||
296 | |||
297 | //-------------------------------- HELPERS --------------------------------------------------------------------// | ||
298 | |||
299 | public ContentManagementEntity GetMetaGroupByPrim(LLUUID uuid) | ||
300 | { | 314 | { |
301 | foreach (Object ent in m_MetaEntityCollection.Entities.Values) | 315 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); |
316 | if (group == null) | ||
317 | return null; | ||
318 | foreach(SceneObjectPart part in group.Children.Values) | ||
302 | { | 319 | { |
303 | if (((ContentManagementEntity)ent).HasChildPrim(uuid)) | 320 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) |
304 | return (ContentManagementEntity)ent; | 321 | { |
322 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new LLVector3(0,254,0), part.Scale); | ||
323 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); | ||
324 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); | ||
325 | } | ||
305 | } | 326 | } |
306 | return null; | 327 | return auraList; |
307 | } | 328 | } |
308 | } | 329 | |
330 | #endregion Public Methods | ||
331 | } | ||
309 | } \ No newline at end of file | 332 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs index f8b0ec9..f801f67 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs | |||
@@ -1,156 +1,181 @@ | |||
1 | #region Header | ||
2 | |||
1 | // CMView.cs created with MonoDevelop | 3 | // CMView.cs created with MonoDevelop |
2 | // User: bongiojp at 11:57 AM 7/3/2008 | 4 | // User: bongiojp at 11:57 AM 7/3/2008 |
3 | // | 5 | // |
4 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers | 6 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers |
5 | // | 7 | // |
6 | 8 | ||
9 | #endregion Header | ||
10 | |||
7 | using System; | 11 | using System; |
8 | using System.Collections.Generic; | ||
9 | using System.Collections; | 12 | using System.Collections; |
13 | using System.Collections.Generic; | ||
14 | |||
10 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
11 | using OpenSim; | 17 | using OpenSim; |
12 | using OpenSim.Framework; | 18 | using OpenSim.Framework; |
13 | using OpenSim.Region.Environment.Interfaces; | 19 | using OpenSim.Region.Environment.Interfaces; |
14 | using OpenSim.Region.Environment.Scenes; | 20 | using OpenSim.Region.Environment.Scenes; |
15 | using log4net; | ||
16 | using OpenSim.Region.Physics.Manager; | 21 | using OpenSim.Region.Physics.Manager; |
22 | |||
23 | using log4net; | ||
24 | |||
17 | using Axiom.Math; | 25 | using Axiom.Math; |
18 | 26 | ||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 27 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
20 | { | 28 | { |
21 | 29 | public class CMView | |
22 | public class CMView | 30 | { |
23 | { | 31 | #region Static Fields |
24 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 32 | |
25 | CMModel m_model = null; | 33 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
26 | 34 | ||
27 | public CMView() | 35 | #endregion Static Fields |
28 | {} | 36 | |
29 | 37 | #region Fields | |
30 | public void Initialise(CMModel model) | 38 | |
31 | { | 39 | CMModel m_model = null; |
32 | m_model = model; | 40 | |
33 | } | 41 | #endregion Fields |
34 | 42 | ||
35 | public void SendMetaEntitiesToNewClient(IClientAPI client) | 43 | #region Constructors |
36 | { | 44 | |
37 | } | 45 | public CMView() |
38 | 46 | { | |
39 | /// <summary> | 47 | } |
40 | /// update all clients of red/green/blue auras and meta entities that the model knows about. | 48 | |
41 | /// </summary> | 49 | #endregion Constructors |
42 | public void DisplayRecentChanges() | 50 | |
43 | { | 51 | #region Public Methods |
44 | m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects."); | 52 | |
45 | DisplayEntities(m_model.MetaEntityCollection); | 53 | // Auras To |
46 | DisplayAuras(m_model.MetaEntityCollection); | 54 | public void DisplayAuras(CMEntityCollection auraCollection) |
47 | } | 55 | { |
48 | 56 | foreach( Object ent in auraCollection.Auras.Values) | |
49 | /// <summary> | 57 | ((AuraMetaEntity)ent).SendFullUpdateToAll(); |
50 | /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted. | 58 | } |
51 | /// If it's a new scene object, any green aura attached to it is deleted. | 59 | |
52 | /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will | 60 | // Auras To Client |
53 | /// figure out that there should be a red aura and not a blue aura/beam. | 61 | public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client) |
54 | /// </summary> | 62 | { |
55 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) | 63 | foreach( Object ent in auraCollection.Auras.Values) |
56 | { | 64 | ((AuraMetaEntity)ent).SendFullUpdate(client); |
57 | // Deal with revisioned parts that have been deleted. | 65 | } |
58 | if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID)) | 66 | |
59 | ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); | 67 | // Auras from List To ALL |
60 | 68 | public void DisplayAuras(ArrayList list) | |
61 | // Deal with new parts not revisioned that have been deleted. | 69 | { |
62 | foreach(SceneObjectPart part in group.Children.Values) | 70 | foreach( Object ent in list) |
63 | if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 71 | { |
64 | ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); | 72 | m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW"); |
65 | } | 73 | ((AuraMetaEntity)ent).SendFullUpdateToAll(); |
66 | 74 | } | |
67 | // Auras To | 75 | } |
68 | public void DisplayAuras(CMEntityCollection auraCollection) | 76 | |
69 | { | 77 | // Entities to ALL |
70 | foreach( Object ent in auraCollection.Auras.Values) | 78 | public void DisplayEntities(CMEntityCollection entityCollection) |
71 | ((AuraMetaEntity)ent).SendFullUpdateToAll(); | 79 | { |
72 | } | 80 | foreach( Object ent in entityCollection.Entities.Values) |
73 | 81 | ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); | |
74 | // Entities to ALL | 82 | } |
75 | public void DisplayEntities(CMEntityCollection entityCollection) | 83 | |
76 | { | 84 | // Entities to Client |
77 | foreach( Object ent in entityCollection.Entities.Values) | 85 | public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client) |
78 | ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); | 86 | { |
79 | } | 87 | foreach( Object ent in entityCollection.Entities.Values) |
80 | 88 | ((ContentManagementEntity)ent).SendFullDiffUpdate(client); | |
81 | // Auras To Client | 89 | } |
82 | public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client) | 90 | |
83 | { | 91 | // Entities from List to ALL |
84 | foreach( Object ent in auraCollection.Auras.Values) | 92 | public void DisplayEntities(ArrayList list) |
85 | ((AuraMetaEntity)ent).SendFullUpdate(client); | 93 | { |
86 | } | 94 | foreach( Object ent in list) |
87 | 95 | ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); | |
88 | // Entities to Client | 96 | } |
89 | public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client) | 97 | |
90 | { | 98 | // Entity to ALL |
91 | foreach( Object ent in entityCollection.Entities.Values) | 99 | public void DisplayEntity(ContentManagementEntity ent) |
92 | ((ContentManagementEntity)ent).SendFullDiffUpdate(client); | 100 | { |
93 | } | 101 | ent.SendFullDiffUpdateToAll(); |
94 | 102 | } | |
95 | // Entity to ALL | 103 | |
96 | public void DisplayEntity(ContentManagementEntity ent) | 104 | public void DisplayHelpMenu(Scene scene) |
97 | { | 105 | { |
98 | ent.SendFullDiffUpdateToAll(); | 106 | string menu = "Menu:\n"; |
99 | } | 107 | menu += "commit (ci) - saves current state of the region to a database on the server\n"; |
100 | 108 | menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n"; | |
101 | public void DisplayMetaEntity(LLUUID uuid) | 109 | SendSimChatMessage(scene, menu); |
102 | { | 110 | } |
103 | ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid); | 111 | |
104 | if (group != null) | 112 | public void DisplayMetaEntity(LLUUID uuid) |
105 | group.SendFullDiffUpdateToAll(); | 113 | { |
106 | } | 114 | ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid); |
107 | 115 | if (group != null) | |
108 | // Auras from List To ALL | 116 | group.SendFullDiffUpdateToAll(); |
109 | public void DisplayAuras(ArrayList list) | 117 | } |
110 | { | 118 | |
111 | foreach( Object ent in list) | 119 | /// <summary> |
112 | { | 120 | /// update all clients of red/green/blue auras and meta entities that the model knows about. |
113 | m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW"); | 121 | /// </summary> |
114 | ((AuraMetaEntity)ent).SendFullUpdateToAll(); | 122 | public void DisplayRecentChanges() |
115 | } | 123 | { |
116 | } | 124 | m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects."); |
117 | 125 | DisplayEntities(m_model.MetaEntityCollection); | |
118 | // Entities from List to ALL | 126 | DisplayAuras(m_model.MetaEntityCollection); |
119 | public void DisplayEntities(ArrayList list) | 127 | } |
120 | { | 128 | |
121 | foreach( Object ent in list) | 129 | public void Hide(ContentManagementEntity ent) |
122 | ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); | 130 | { |
123 | } | 131 | ent.HideFromAll(); |
124 | 132 | } | |
125 | public void DisplayHelpMenu(Scene scene) | 133 | |
126 | { | 134 | public void HideAllAuras() |
127 | string menu = "Menu:\n"; | 135 | { |
128 | menu += "commit (ci) - saves current state of the region to a database on the server\n"; | 136 | foreach(Object obj in m_model.MetaEntityCollection.Auras.Values) |
129 | menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n"; | 137 | ((MetaEntity)obj).HideFromAll(); |
130 | SendSimChatMessage(scene, menu); | 138 | } |
131 | } | 139 | |
132 | 140 | public void HideAllMetaEntities() | |
133 | public void SendSimChatMessage(Scene scene, string message) | 141 | { |
134 | { | 142 | foreach(Object obj in m_model.MetaEntityCollection.Entities.Values) |
135 | scene.SimChat(Helpers.StringToField(message), | 143 | ((ContentManagementEntity)obj).HideFromAll(); |
136 | ChatTypeEnum.Broadcast, 0, new LLVector3(0,0,0), "Content Manager", LLUUID.Zero, false); | 144 | } |
137 | } | 145 | |
138 | 146 | public void Initialise(CMModel model) | |
139 | public void Hide(ContentManagementEntity ent) | 147 | { |
140 | { | 148 | m_model = model; |
141 | ent.HideFromAll(); | 149 | } |
142 | } | 150 | |
143 | 151 | /// <summary> | |
144 | public void HideAllMetaEntities() | 152 | /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted. |
145 | { | 153 | /// If it's a new scene object, any green aura attached to it is deleted. |
146 | foreach(Object obj in m_model.MetaEntityCollection.Entities.Values) | 154 | /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will |
147 | ((ContentManagementEntity)obj).HideFromAll(); | 155 | /// figure out that there should be a red aura and not a blue aura/beam. |
148 | } | 156 | /// </summary> |
149 | 157 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) | |
150 | public void HideAllAuras() | 158 | { |
151 | { | 159 | // Deal with revisioned parts that have been deleted. |
152 | foreach(Object obj in m_model.MetaEntityCollection.Auras.Values) | 160 | if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID)) |
153 | ((MetaEntity)obj).HideFromAll(); | 161 | ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); |
154 | } | 162 | |
155 | } | 163 | // Deal with new parts not revisioned that have been deleted. |
156 | } | 164 | foreach(SceneObjectPart part in group.Children.Values) |
165 | if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
166 | ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); | ||
167 | } | ||
168 | |||
169 | public void SendMetaEntitiesToNewClient(IClientAPI client) | ||
170 | { | ||
171 | } | ||
172 | |||
173 | public void SendSimChatMessage(Scene scene, string message) | ||
174 | { | ||
175 | scene.SimChat(Helpers.StringToField(message), | ||
176 | ChatTypeEnum.Broadcast, 0, new LLVector3(0,0,0), "Content Manager", LLUUID.Zero, false); | ||
177 | } | ||
178 | |||
179 | #endregion Public Methods | ||
180 | } | ||
181 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs index fb9df8f..bdf8560 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs | |||
@@ -1,326 +1,362 @@ | |||
1 | #region Header | ||
2 | |||
1 | // ContentManagementEntity.cs | 3 | // ContentManagementEntity.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | // | 5 | // |
4 | // | 6 | // |
5 | 7 | ||
8 | #endregion Header | ||
9 | |||
6 | using System; | 10 | using System; |
7 | using System.Collections.Generic; | 11 | using System.Collections.Generic; |
8 | using System.Drawing; | 12 | using System.Drawing; |
13 | |||
9 | using libsecondlife; | 14 | using libsecondlife; |
15 | |||
10 | using Nini.Config; | 16 | using Nini.Config; |
17 | |||
11 | using OpenSim.Framework; | 18 | using OpenSim.Framework; |
12 | using OpenSim.Region.Environment.Interfaces; | 19 | using OpenSim.Region.Environment.Interfaces; |
13 | using OpenSim.Region.Environment.Scenes; | 20 | using OpenSim.Region.Environment.Scenes; |
14 | using log4net; | ||
15 | using OpenSim.Region.Physics.Manager; | 21 | using OpenSim.Region.Physics.Manager; |
22 | |||
23 | using log4net; | ||
24 | |||
16 | using Axiom.Math; | 25 | using Axiom.Math; |
17 | 26 | ||
18 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 27 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
19 | { | 28 | { |
20 | public class ContentManagementEntity : MetaEntity | 29 | public class ContentManagementEntity : MetaEntity |
21 | { | 30 | { |
22 | static float TimeToDiff = 0; | 31 | #region Static Fields |
23 | static float TimeToCreateEntities = 0; | 32 | |
24 | 33 | static float TimeToDiff = 0; | |
25 | // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different. | 34 | static float TimeToCreateEntities = 0; |
26 | // This can come in handy. | 35 | |
27 | protected SceneObjectGroup m_UnchangedEntity = null; | 36 | #endregion Static Fields |
28 | protected Dictionary<LLUUID, BeamMetaEntity> m_BeamEntities = new Dictionary<LLUUID, BeamMetaEntity>(); | 37 | |
29 | protected Dictionary<LLUUID, AuraMetaEntity> m_AuraEntities = new Dictionary<LLUUID, AuraMetaEntity>(); | 38 | #region Fields |
30 | 39 | ||
31 | /// <value> | 40 | protected Dictionary<LLUUID, AuraMetaEntity> m_AuraEntities = new Dictionary<LLUUID, AuraMetaEntity>(); |
32 | /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list. | 41 | protected Dictionary<LLUUID, BeamMetaEntity> m_BeamEntities = new Dictionary<LLUUID, BeamMetaEntity>(); |
33 | /// </value> | 42 | |
34 | bool DiffersFromSceneGroup = false; | 43 | // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different. |
35 | 44 | // This can come in handy. | |
36 | public SceneObjectGroup UnchangedEntity | 45 | protected SceneObjectGroup m_UnchangedEntity = null; |
37 | { | 46 | |
38 | get { return m_UnchangedEntity; } | 47 | /// <value> |
39 | } | 48 | /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list. |
40 | 49 | /// </value> | |
41 | public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics) : base(Unchanged, false) | 50 | bool DiffersFromSceneGroup = false; |
42 | { | 51 | |
43 | m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false); | 52 | #endregion Fields |
44 | } | 53 | |
45 | 54 | #region Constructors | |
46 | public ContentManagementEntity(string objectXML, Scene scene, bool physics) : base(objectXML, scene, false) | 55 | |
47 | { | 56 | public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics) |
48 | m_UnchangedEntity = new SceneObjectGroup(objectXML); | 57 | : base(Unchanged, false) |
49 | } | 58 | { |
50 | 59 | m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false); | |
51 | public override void Hide(IClientAPI client) | 60 | } |
52 | { | 61 | |
53 | base.Hide(client); | 62 | public ContentManagementEntity(string objectXML, Scene scene, bool physics) |
54 | foreach(MetaEntity group in m_AuraEntities.Values) | 63 | : base(objectXML, scene, false) |
55 | group.Hide(client); | 64 | { |
56 | foreach(MetaEntity group in m_BeamEntities.Values) | 65 | m_UnchangedEntity = new SceneObjectGroup(objectXML); |
57 | group.Hide(client); | 66 | } |
58 | } | 67 | |
59 | 68 | #endregion Constructors | |
60 | public override void HideFromAll() | 69 | |
61 | { | 70 | #region Public Properties |
62 | base.HideFromAll(); | 71 | |
63 | foreach(MetaEntity group in m_AuraEntities.Values) | 72 | public SceneObjectGroup UnchangedEntity |
64 | group.HideFromAll(); | 73 | { |
65 | foreach(MetaEntity group in m_BeamEntities.Values) | 74 | get { return m_UnchangedEntity; } |
66 | group.HideFromAll(); | 75 | } |
67 | } | 76 | |
68 | 77 | #endregion Public Properties | |
69 | public void SendFullDiffUpdateToAll() | 78 | |
70 | { | 79 | #region Private Methods |
71 | FindDifferences(); | 80 | |
72 | if (DiffersFromSceneGroup) | 81 | /// <summary> |
73 | { | 82 | /// Check if an entitybase list (like that returned by scene.GetEntities() ) contains a group with the rootpart uuid that matches the current uuid. |
74 | SendFullUpdateToAll(); | 83 | /// </summary> |
75 | SendFullAuraUpdateToAll(); | 84 | private bool ContainsKey(List<EntityBase> list, LLUUID uuid) |
76 | SendFullBeamUpdateToAll(); | 85 | { |
77 | } | 86 | foreach( EntityBase part in list) |
78 | } | 87 | if (part.UUID == uuid) |
79 | 88 | return true; | |
80 | public void SendFullDiffUpdate(IClientAPI client) | 89 | return false; |
81 | { | 90 | } |
82 | FindDifferences(); | 91 | |
83 | if (DiffersFromSceneGroup) | 92 | private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, LLUUID uuid) |
84 | { | 93 | { |
85 | SendFullUpdate(client); | 94 | foreach (EntityBase ent in list) |
86 | SendFullAuraUpdate(client); | 95 | { |
87 | SendFullBeamUpdate(client); | 96 | if (ent is SceneObjectGroup) |
88 | } | 97 | if (ent.UUID == uuid) |
89 | } | 98 | return (SceneObjectGroup)ent; |
90 | 99 | } | |
91 | public void SendFullBeamUpdate(IClientAPI client) | 100 | return null; |
92 | { | 101 | } |
93 | if (DiffersFromSceneGroup) | 102 | |
94 | { | 103 | #endregion Private Methods |
95 | foreach(BeamMetaEntity group in m_BeamEntities.Values) | 104 | |
96 | group.SendFullUpdate(client); | 105 | #region Public Methods |
97 | } | 106 | |
98 | } | 107 | /// <summary> |
99 | 108 | /// 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. | |
100 | public void SendFullAuraUpdate(IClientAPI client) | 109 | /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately. |
101 | { | 110 | /// </summary> |
102 | if (DiffersFromSceneGroup) | 111 | public void FindDifferences() |
103 | { | 112 | { |
104 | foreach(AuraMetaEntity group in m_AuraEntities.Values) | 113 | System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities(); |
105 | group.SendFullUpdate(client); | 114 | DiffersFromSceneGroup = false; |
106 | } | 115 | // if group is not contained in scene's list |
107 | } | 116 | if(!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) |
108 | 117 | { | |
109 | public void SendFullBeamUpdateToAll() | 118 | foreach(SceneObjectPart part in m_UnchangedEntity.Children.Values) |
110 | { | 119 | { |
111 | if (DiffersFromSceneGroup) | 120 | // if scene list no longer contains this part, display translucent part and mark with red aura |
112 | { | 121 | if(! ContainsKey(sceneEntityList, part.UUID)) |
113 | foreach(BeamMetaEntity group in m_BeamEntities.Values) | 122 | { |
114 | group.SendFullUpdateToAll(); | 123 | // if already displaying a red aura over part, make sure its red |
115 | } | 124 | if (m_AuraEntities.ContainsKey(part.UUID)) |
116 | } | 125 | { |
117 | 126 | m_AuraEntities[part.UUID].SetAura(new LLVector3(254,0,0), part.Scale); | |
118 | public void SendFullAuraUpdateToAll() | 127 | } |
119 | { | 128 | else |
120 | if (DiffersFromSceneGroup) | 129 | { |
121 | { | 130 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, |
122 | foreach(AuraMetaEntity group in m_AuraEntities.Values) | 131 | m_Entity.Scene.PrimIDAllocate(), |
123 | group.SendFullUpdateToAll(); | 132 | part.GetWorldPosition(), |
124 | } | 133 | MetaEntity.TRANSLUCENT, |
125 | } | 134 | new LLVector3(254,0,0), |
126 | 135 | part.Scale | |
127 | /// <summary> | 136 | ); |
128 | /// 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. | 137 | m_AuraEntities.Add(part.UUID, auraGroup); |
129 | /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately. | 138 | } |
130 | /// </summary> | 139 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); |
131 | public void FindDifferences() | 140 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); |
132 | { | 141 | } |
133 | System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities(); | 142 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id |
134 | DiffersFromSceneGroup = false; | 143 | } |
135 | // if group is not contained in scene's list | 144 | |
136 | if(!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) | 145 | // a deleted part has no where to point a beam particle system, |
137 | { | 146 | // if a metapart had a particle system (maybe it represented a moved part) remove it |
138 | foreach(SceneObjectPart part in m_UnchangedEntity.Children.Values) | 147 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) |
139 | { | 148 | { |
140 | // if scene list no longer contains this part, display translucent part and mark with red aura | 149 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); |
141 | if(! ContainsKey(sceneEntityList, part.UUID)) | 150 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); |
142 | { | 151 | } |
143 | // if already displaying a red aura over part, make sure its red | 152 | |
144 | if (m_AuraEntities.ContainsKey(part.UUID)) | 153 | DiffersFromSceneGroup = true; |
145 | { | 154 | } |
146 | m_AuraEntities[part.UUID].SetAura(new LLVector3(254,0,0), part.Scale); | 155 | // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately |
147 | } | 156 | else |
148 | else | 157 | { |
149 | { | 158 | MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID)); |
150 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | 159 | } |
151 | m_Entity.Scene.PrimIDAllocate(), | 160 | } |
152 | part.GetWorldPosition(), | 161 | |
153 | MetaEntity.TRANSLUCENT, | 162 | /// <summary> |
154 | new LLVector3(254,0,0), | 163 | /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID. |
155 | part.Scale | 164 | /// </summary> |
156 | ); | 165 | public bool HasChildPrim(LLUUID uuid) |
157 | m_AuraEntities.Add(part.UUID, auraGroup); | 166 | { |
158 | } | 167 | if (m_UnchangedEntity.Children.ContainsKey(uuid)) |
159 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); | 168 | return true; |
160 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); | 169 | return false; |
161 | } | 170 | } |
162 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id | 171 | |
163 | } | 172 | /// <summary> |
164 | 173 | /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId. | |
165 | // a deleted part has no where to point a beam particle system, | 174 | /// </summary> |
166 | // if a metapart had a particle system (maybe it represented a moved part) remove it | 175 | public bool HasChildPrim(uint localID) |
167 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | 176 | { |
168 | { | 177 | foreach( SceneObjectPart part in m_UnchangedEntity.Children.Values) |
169 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | 178 | if ( part.LocalId == localID ) |
170 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | 179 | return true; |
171 | } | 180 | return false; |
172 | 181 | } | |
173 | DiffersFromSceneGroup = true; | 182 | |
174 | } | 183 | public override void Hide(IClientAPI client) |
175 | // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately | 184 | { |
176 | else | 185 | base.Hide(client); |
177 | { | 186 | foreach(MetaEntity group in m_AuraEntities.Values) |
178 | MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID)); | 187 | group.Hide(client); |
179 | } | 188 | foreach(MetaEntity group in m_BeamEntities.Values) |
180 | } | 189 | group.Hide(client); |
181 | 190 | } | |
182 | /// <summary> | 191 | |
183 | /// Returns true if there was a change between meta entity and the entity group, false otherwise. | 192 | public override void HideFromAll() |
184 | /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated). | 193 | { |
185 | /// </summary> | 194 | base.HideFromAll(); |
186 | public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup) | 195 | foreach(MetaEntity group in m_AuraEntities.Values) |
187 | { | 196 | group.HideFromAll(); |
188 | SceneObjectPart sceneEntityPart; | 197 | foreach(MetaEntity group in m_BeamEntities.Values) |
189 | SceneObjectPart metaEntityPart; | 198 | group.HideFromAll(); |
190 | Diff differences; | 199 | } |
191 | bool changed = false; | 200 | |
192 | 201 | /// <summary> | |
193 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user | 202 | /// Returns true if there was a change between meta entity and the entity group, false otherwise. |
194 | // had originally saved. | 203 | /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated). |
195 | // m_Entity will NOT necessarily be the same entity as the user had saved. | 204 | /// </summary> |
196 | foreach(SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) | 205 | public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup) |
197 | { | ||
198 | //This is the part that we use to show changes. | ||
199 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); | ||
200 | if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) | ||
201 | { | ||
202 | sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; | ||
203 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); | ||
204 | if (differences != Diff.NONE) | ||
205 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); | ||
206 | if (differences != 0) | ||
207 | { | ||
208 | // Root Part that has been modified | ||
209 | if ((differences&Diff.POSITION) > 0) | ||
210 | { | ||
211 | // If the position of any part has changed, make sure the RootPart of the | ||
212 | // meta entity is pointing with a beam particle system | ||
213 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
214 | { | ||
215 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
216 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
217 | } | ||
218 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, | ||
219 | m_Entity.Scene.PrimIDAllocate(), | ||
220 | m_UnchangedEntity.RootPart.GetWorldPosition(), | ||
221 | MetaEntity.TRANSLUCENT, | ||
222 | sceneEntityPart, | ||
223 | new LLVector3(0,0,254) | ||
224 | ); | ||
225 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); | ||
226 | } | ||
227 | |||
228 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
229 | { | ||
230 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
231 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
232 | } | ||
233 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
234 | m_Entity.Scene.PrimIDAllocate(), | ||
235 | UnchangedPart.GetWorldPosition(), | ||
236 | MetaEntity.TRANSLUCENT, | ||
237 | new LLVector3(0,0,254), | ||
238 | UnchangedPart.Scale | ||
239 | ); | ||
240 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
241 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
242 | |||
243 | DiffersFromSceneGroup = true; | ||
244 | } | ||
245 | else // no differences between scene part and meta part | ||
246 | { | ||
247 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
248 | { | ||
249 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
250 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
251 | } | ||
252 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
253 | { | ||
254 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
255 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
256 | } | ||
257 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); | ||
258 | } | ||
259 | } | ||
260 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
261 | { | ||
262 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
263 | { | ||
264 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
265 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
266 | } | ||
267 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
268 | m_Entity.Scene.PrimIDAllocate(), | ||
269 | UnchangedPart.GetWorldPosition(), | ||
270 | MetaEntity.TRANSLUCENT, | ||
271 | new LLVector3(254,0,0), | ||
272 | UnchangedPart.Scale | ||
273 | ); | ||
274 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
275 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
276 | |||
277 | DiffersFromSceneGroup = true; | ||
278 | } | ||
279 | } | ||
280 | return changed; | ||
281 | } | ||
282 | |||
283 | private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, LLUUID uuid) | ||
284 | { | 206 | { |
285 | foreach (EntityBase ent in list) | 207 | SceneObjectPart sceneEntityPart; |
286 | { | 208 | SceneObjectPart metaEntityPart; |
287 | if (ent is SceneObjectGroup) | 209 | Diff differences; |
288 | if (ent.UUID == uuid) | 210 | bool changed = false; |
289 | return (SceneObjectGroup)ent; | 211 | |
290 | } | 212 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user |
291 | return null; | 213 | // had originally saved. |
292 | } | 214 | // m_Entity will NOT necessarily be the same entity as the user had saved. |
293 | 215 | foreach(SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) | |
294 | /// <summary> | 216 | { |
295 | /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID. | 217 | //This is the part that we use to show changes. |
296 | /// </summary> | 218 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); |
297 | public bool HasChildPrim(LLUUID uuid) | 219 | if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) |
298 | { | 220 | { |
299 | if (m_UnchangedEntity.Children.ContainsKey(uuid)) | 221 | sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; |
300 | return true; | 222 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); |
301 | return false; | 223 | if (differences != Diff.NONE) |
302 | } | 224 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); |
303 | 225 | if (differences != 0) | |
304 | /// <summary> | 226 | { |
305 | /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId. | 227 | // Root Part that has been modified |
306 | /// </summary> | 228 | if ((differences&Diff.POSITION) > 0) |
307 | public bool HasChildPrim(uint localID) | 229 | { |
308 | { | 230 | // If the position of any part has changed, make sure the RootPart of the |
309 | foreach( SceneObjectPart part in m_UnchangedEntity.Children.Values) | 231 | // meta entity is pointing with a beam particle system |
310 | if ( part.LocalId == localID ) | 232 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) |
311 | return true; | 233 | { |
312 | return false; | 234 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); |
313 | } | 235 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); |
314 | 236 | } | |
315 | /// <summary> | 237 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, |
316 | /// Check if an entitybase list (like that returned by scene.GetEntities() ) contains a group with the rootpart uuid that matches the current uuid. | 238 | m_Entity.Scene.PrimIDAllocate(), |
317 | /// </summary> | 239 | m_UnchangedEntity.RootPart.GetWorldPosition(), |
318 | private bool ContainsKey(List<EntityBase> list, LLUUID uuid) | 240 | MetaEntity.TRANSLUCENT, |
319 | { | 241 | sceneEntityPart, |
320 | foreach( EntityBase part in list) | 242 | new LLVector3(0,0,254) |
321 | if (part.UUID == uuid) | 243 | ); |
322 | return true; | 244 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); |
323 | return false; | 245 | } |
324 | } | 246 | |
325 | } | 247 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) |
326 | } | 248 | { |
249 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
250 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
251 | } | ||
252 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
253 | m_Entity.Scene.PrimIDAllocate(), | ||
254 | UnchangedPart.GetWorldPosition(), | ||
255 | MetaEntity.TRANSLUCENT, | ||
256 | new LLVector3(0,0,254), | ||
257 | UnchangedPart.Scale | ||
258 | ); | ||
259 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
260 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
261 | |||
262 | DiffersFromSceneGroup = true; | ||
263 | } | ||
264 | else // no differences between scene part and meta part | ||
265 | { | ||
266 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
267 | { | ||
268 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
269 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
270 | } | ||
271 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
272 | { | ||
273 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
274 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
275 | } | ||
276 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); | ||
277 | } | ||
278 | } | ||
279 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
280 | { | ||
281 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
282 | { | ||
283 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
284 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
285 | } | ||
286 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
287 | m_Entity.Scene.PrimIDAllocate(), | ||
288 | UnchangedPart.GetWorldPosition(), | ||
289 | MetaEntity.TRANSLUCENT, | ||
290 | new LLVector3(254,0,0), | ||
291 | UnchangedPart.Scale | ||
292 | ); | ||
293 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
294 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
295 | |||
296 | DiffersFromSceneGroup = true; | ||
297 | } | ||
298 | } | ||
299 | return changed; | ||
300 | } | ||
301 | |||
302 | public void SendFullAuraUpdate(IClientAPI client) | ||
303 | { | ||
304 | if (DiffersFromSceneGroup) | ||
305 | { | ||
306 | foreach(AuraMetaEntity group in m_AuraEntities.Values) | ||
307 | group.SendFullUpdate(client); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | public void SendFullAuraUpdateToAll() | ||
312 | { | ||
313 | if (DiffersFromSceneGroup) | ||
314 | { | ||
315 | foreach(AuraMetaEntity group in m_AuraEntities.Values) | ||
316 | group.SendFullUpdateToAll(); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | public void SendFullBeamUpdate(IClientAPI client) | ||
321 | { | ||
322 | if (DiffersFromSceneGroup) | ||
323 | { | ||
324 | foreach(BeamMetaEntity group in m_BeamEntities.Values) | ||
325 | group.SendFullUpdate(client); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | public void SendFullBeamUpdateToAll() | ||
330 | { | ||
331 | if (DiffersFromSceneGroup) | ||
332 | { | ||
333 | foreach(BeamMetaEntity group in m_BeamEntities.Values) | ||
334 | group.SendFullUpdateToAll(); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | public void SendFullDiffUpdate(IClientAPI client) | ||
339 | { | ||
340 | FindDifferences(); | ||
341 | if (DiffersFromSceneGroup) | ||
342 | { | ||
343 | SendFullUpdate(client); | ||
344 | SendFullAuraUpdate(client); | ||
345 | SendFullBeamUpdate(client); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | public void SendFullDiffUpdateToAll() | ||
350 | { | ||
351 | FindDifferences(); | ||
352 | if (DiffersFromSceneGroup) | ||
353 | { | ||
354 | SendFullUpdateToAll(); | ||
355 | SendFullAuraUpdateToAll(); | ||
356 | SendFullBeamUpdateToAll(); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | #endregion Public Methods | ||
361 | } | ||
362 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs index 413d00d..ef27f46 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs | |||
@@ -1,31 +1,69 @@ | |||
1 | #region Header | ||
2 | |||
1 | // ContentManagementModule.cs | 3 | // ContentManagementModule.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | 5 | ||
6 | #endregion Header | ||
7 | |||
4 | using System; | 8 | using System; |
5 | using System.Collections.Generic; | 9 | using System.Collections.Generic; |
10 | using System.Threading; | ||
11 | |||
6 | using libsecondlife; | 12 | using libsecondlife; |
13 | |||
7 | using Nini.Config; | 14 | using Nini.Config; |
15 | |||
8 | using OpenSim; | 16 | using OpenSim; |
9 | using OpenSim.Framework; | 17 | using OpenSim.Framework; |
10 | using OpenSim.Region.Environment.Interfaces; | 18 | using OpenSim.Region.Environment.Interfaces; |
11 | using OpenSim.Region.Environment.Scenes; | 19 | using OpenSim.Region.Environment.Scenes; |
12 | using log4net; | ||
13 | using OpenSim.Region.Physics.Manager; | 20 | using OpenSim.Region.Physics.Manager; |
21 | |||
22 | using log4net; | ||
23 | |||
14 | using Axiom.Math; | 24 | using Axiom.Math; |
15 | using System.Threading; | 25 | |
16 | |||
17 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 26 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
18 | { | 27 | { |
19 | public class ContentManagementModule : IRegionModule | 28 | public class ContentManagementModule : IRegionModule |
20 | { | 29 | { |
30 | #region Static Fields | ||
31 | |||
21 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 32 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
33 | |||
34 | #endregion Static Fields | ||
35 | |||
36 | #region Fields | ||
37 | |||
38 | bool initialised = false; | ||
22 | CMController m_control = null; | 39 | CMController m_control = null; |
40 | bool m_enabled = false; | ||
23 | CMModel m_model = null; | 41 | CMModel m_model = null; |
24 | CMView m_view = null; | ||
25 | bool initialised = false; | ||
26 | bool m_posted = false; | 42 | bool m_posted = false; |
27 | bool m_enabled = false; | 43 | CMView m_view = null; |
28 | 44 | ||
45 | #endregion Fields | ||
46 | |||
47 | #region Public Properties | ||
48 | |||
49 | public bool IsSharedModule | ||
50 | { | ||
51 | get { return true; } | ||
52 | } | ||
53 | |||
54 | public string Name | ||
55 | { | ||
56 | get { return "ContentManagementModule"; } | ||
57 | } | ||
58 | |||
59 | #endregion Public Properties | ||
60 | |||
61 | #region Public Methods | ||
62 | |||
63 | public void Close() | ||
64 | { | ||
65 | } | ||
66 | |||
29 | public void Initialise(Scene scene, IConfigSource source) | 67 | public void Initialise(Scene scene, IConfigSource source) |
30 | { | 68 | { |
31 | string databaseDir = "./"; | 69 | string databaseDir = "./"; |
@@ -52,13 +90,13 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
52 | m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e); | 90 | m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e); |
53 | m_enabled = false; | 91 | m_enabled = false; |
54 | } | 92 | } |
55 | 93 | ||
56 | if (!m_enabled) | 94 | if (!m_enabled) |
57 | { | 95 | { |
58 | m_log.Info("[Content Management]: Content Management System is not Enabled."); | 96 | m_log.Info("[Content Management]: Content Management System is not Enabled."); |
59 | return; | 97 | return; |
60 | } | 98 | } |
61 | 99 | ||
62 | lock(this) | 100 | lock(this) |
63 | { | 101 | { |
64 | if (!initialised) //only init once | 102 | if (!initialised) //only init once |
@@ -79,12 +117,12 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
79 | } | 117 | } |
80 | } | 118 | } |
81 | } | 119 | } |
82 | 120 | ||
83 | public void PostInitialise() | 121 | public void PostInitialise() |
84 | { | 122 | { |
85 | if (! m_enabled) | 123 | if (! m_enabled) |
86 | return; | 124 | return; |
87 | 125 | ||
88 | lock(this) | 126 | lock(this) |
89 | { | 127 | { |
90 | if (!m_posted) //only post once | 128 | if (!m_posted) //only post once |
@@ -94,18 +132,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
94 | } | 132 | } |
95 | } | 133 | } |
96 | } | 134 | } |
97 | |||
98 | public void Close() | ||
99 | {} | ||
100 | |||
101 | public string Name | ||
102 | { | ||
103 | get { return "ContentManagementModule"; } | ||
104 | } | ||
105 | 135 | ||
106 | public bool IsSharedModule | 136 | #endregion Public Methods |
107 | { | ||
108 | get { return true; } | ||
109 | } | ||
110 | } | 137 | } |
111 | } | 138 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs index e1f519b..680cefbd 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs | |||
@@ -1,159 +1,132 @@ | |||
1 | #region Header | ||
2 | |||
1 | // FileSystemDatabase.cs | 3 | // FileSystemDatabase.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | 5 | ||
6 | #endregion Header | ||
7 | |||
4 | using System; | 8 | using System; |
5 | using System.Collections.Generic; | 9 | using System.Collections.Generic; |
10 | using System.Diagnostics; | ||
6 | using System.IO; | 11 | using System.IO; |
12 | using Slash = System.IO.Path; | ||
7 | using System.Reflection; | 13 | using System.Reflection; |
8 | using System.Xml; | 14 | using System.Xml; |
15 | |||
9 | using libsecondlife; | 16 | using libsecondlife; |
17 | |||
10 | using Nini.Config; | 18 | using Nini.Config; |
19 | |||
11 | using OpenSim.Framework; | 20 | using OpenSim.Framework; |
12 | using OpenSim.Region.Environment.Interfaces; | 21 | using OpenSim.Region.Environment.Interfaces; |
13 | using OpenSim.Region.Environment.Modules.World.Serialiser; | 22 | using OpenSim.Region.Environment.Modules.World.Serialiser; |
14 | using OpenSim.Region.Environment.Modules.World.Terrain; | 23 | using OpenSim.Region.Environment.Modules.World.Terrain; |
15 | using OpenSim.Region.Environment.Scenes; | 24 | using OpenSim.Region.Environment.Scenes; |
16 | using log4net; | ||
17 | using OpenSim.Region.Physics.Manager; | 25 | using OpenSim.Region.Physics.Manager; |
26 | |||
27 | using log4net; | ||
28 | |||
18 | using Axiom.Math; | 29 | using Axiom.Math; |
19 | using Slash=System.IO.Path; | ||
20 | using System.Diagnostics; | ||
21 | 30 | ||
22 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 31 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
23 | { | 32 | { |
24 | public class FileSystemDatabase : IContentDatabase | 33 | public class FileSystemDatabase : IContentDatabase |
25 | { | 34 | { |
26 | public static float TimeToDownload = 0; | 35 | #region Static Fields |
27 | public static float TimeToSave = 0; | 36 | |
28 | 37 | public static float TimeToDownload = 0; | |
29 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 38 | public static float TimeToSave = 0; |
30 | 39 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | |
31 | private string m_repodir = null; | 40 | |
32 | private Dictionary<LLUUID, IRegionSerialiser> m_serialiser = new Dictionary<LLUUID, IRegionSerialiser>(); | 41 | #endregion Static Fields |
33 | private Dictionary<LLUUID, Scene> m_scenes = new Dictionary<LLUUID, Scene>(); | 42 | |
34 | 43 | #region Fields | |
35 | public FileSystemDatabase() | 44 | |
36 | { | 45 | private string m_repodir = null; |
37 | } | 46 | private Dictionary<LLUUID, Scene> m_scenes = new Dictionary<LLUUID, Scene>(); |
38 | 47 | private Dictionary<LLUUID, IRegionSerialiser> m_serialiser = new Dictionary<LLUUID, IRegionSerialiser>(); | |
39 | public void Initialise(Scene scene, string dir) | 48 | |
40 | { | 49 | #endregion Fields |
41 | lock(this) | 50 | |
42 | { | 51 | #region Constructors |
43 | if (m_repodir == null) | 52 | |
44 | m_repodir = dir; | 53 | public FileSystemDatabase() |
45 | } | 54 | { |
46 | lock(m_scenes) | 55 | } |
47 | m_scenes.Add(scene.RegionInfo.RegionID, scene); | 56 | |
48 | } | 57 | #endregion Constructors |
49 | 58 | ||
50 | 59 | #region Private Methods | |
51 | // Run once and only once. | 60 | |
52 | public void PostInitialise() | 61 | // called by postinitialise |
53 | { | 62 | private void CreateDirectory() |
54 | SetupSerialiser(); | 63 | { |
55 | 64 | string scenedir; | |
56 | m_log.Info("[FSDB]: Creating repository in " + m_repodir + "."); | 65 | if (!Directory.Exists(m_repodir)) |
57 | CreateDirectory(); | 66 | Directory.CreateDirectory(m_repodir); |
58 | } | 67 | |
59 | 68 | foreach (LLUUID region in m_scenes.Keys) | |
60 | // called by postinitialise | 69 | { |
61 | private void SetupSerialiser() | 70 | scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar; |
71 | if (!Directory.Exists(scenedir)) | ||
72 | Directory.CreateDirectory(scenedir); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | // called by postinitialise | ||
77 | private void SetupSerialiser() | ||
62 | { | 78 | { |
63 | if (m_serialiser.Count == 0) | 79 | if (m_serialiser.Count == 0) |
64 | foreach(LLUUID region in m_scenes.Keys) | 80 | foreach(LLUUID region in m_scenes.Keys) |
65 | m_serialiser.Add(region, | 81 | m_serialiser.Add(region, |
66 | m_scenes[region].RequestModuleInterface<IRegionSerialiser>() | 82 | m_scenes[region].RequestModuleInterface<IRegionSerialiser>() |
67 | ); | 83 | ); |
84 | } | ||
85 | |||
86 | #endregion Private Methods | ||
87 | |||
88 | #region Public Methods | ||
89 | |||
90 | public int GetMostRecentRevision(LLUUID regionid) | ||
91 | { | ||
92 | return NumOfRegionRev(regionid); | ||
93 | } | ||
94 | |||
95 | public string GetRegionObjectHeightMap(LLUUID regionid) | ||
96 | { | ||
97 | String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + | ||
98 | Slash.DirectorySeparatorChar + "heightmap.r32"; | ||
99 | FileStream fs = new FileStream( filename, FileMode.Open); | ||
100 | StreamReader sr = new StreamReader(fs); | ||
101 | String result = sr.ReadToEnd(); | ||
102 | sr.Close(); | ||
103 | fs.Close(); | ||
104 | return result; | ||
105 | } | ||
106 | |||
107 | public string GetRegionObjectHeightMap(LLUUID regionid, int revision) | ||
108 | { | ||
109 | String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + | ||
110 | Slash.DirectorySeparatorChar + "heightmap.r32"; | ||
111 | FileStream fs = new FileStream( filename, FileMode.Open); | ||
112 | StreamReader sr = new StreamReader(fs); | ||
113 | String result = sr.ReadToEnd(); | ||
114 | sr.Close(); | ||
115 | fs.Close(); | ||
116 | return result; | ||
68 | } | 117 | } |
69 | 118 | ||
70 | // called by postinitialise | 119 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision) |
71 | private void CreateDirectory() | 120 | { |
72 | { | 121 | System.Collections.ArrayList objectList = new System.Collections.ArrayList(); |
73 | string scenedir; | 122 | string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + |
74 | if (!Directory.Exists(m_repodir)) | 123 | + revision + Slash.DirectorySeparatorChar + "objects.xml"; |
75 | Directory.CreateDirectory(m_repodir); | 124 | XmlDocument doc = new XmlDocument(); |
76 | |||
77 | foreach (LLUUID region in m_scenes.Keys) | ||
78 | { | ||
79 | scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar; | ||
80 | if (!Directory.Exists(scenedir)) | ||
81 | Directory.CreateDirectory(scenedir); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | public int NumOfRegionRev(LLUUID regionid) | ||
86 | { | ||
87 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | ||
88 | m_log.Info("[FSDB]: Reading scene dir: " + scenedir); | ||
89 | string[] directories = Directory.GetDirectories(scenedir); | ||
90 | return directories.Length; | ||
91 | } | ||
92 | |||
93 | public int GetMostRecentRevision(LLUUID regionid) | ||
94 | { | ||
95 | return NumOfRegionRev(regionid); | ||
96 | } | ||
97 | |||
98 | public void SaveRegion(LLUUID regionid, string regionName, string logMessage) | ||
99 | { | ||
100 | m_log.Info("[FSDB]: ..............................."); | ||
101 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | ||
102 | |||
103 | m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir); | ||
104 | if (!Directory.Exists(scenedir)) | ||
105 | Directory.CreateDirectory(scenedir); | ||
106 | |||
107 | int newRevisionNum = GetMostRecentRevision(regionid)+1; | ||
108 | string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar; | ||
109 | |||
110 | m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir); | ||
111 | if (!Directory.Exists(revisiondir)) | ||
112 | Directory.CreateDirectory(revisiondir); | ||
113 | |||
114 | try { | ||
115 | Stopwatch x = new Stopwatch(); | ||
116 | x.Start(); | ||
117 | if (m_scenes.ContainsKey(regionid)) | ||
118 | { | ||
119 | m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir); | ||
120 | } | ||
121 | x.Stop(); | ||
122 | TimeToSave += x.ElapsedMilliseconds; | ||
123 | m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds); | ||
124 | m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave); | ||
125 | } | ||
126 | catch (Exception e) | ||
127 | { | ||
128 | m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | try { | ||
133 | // Finish by writing log message. | ||
134 | FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite); | ||
135 | StreamWriter sw = new StreamWriter(file); | ||
136 | sw.Write(logMessage); | ||
137 | sw.Close(); | ||
138 | } | ||
139 | catch (Exception e) | ||
140 | { | ||
141 | m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e); | ||
142 | return; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision) | ||
147 | { | ||
148 | System.Collections.ArrayList objectList = new System.Collections.ArrayList(); | ||
149 | string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + | ||
150 | + revision + Slash.DirectorySeparatorChar + "objects.xml"; | ||
151 | XmlDocument doc = new XmlDocument(); | ||
152 | XmlNode rootNode; | 125 | XmlNode rootNode; |
153 | //int primCount = 0; | 126 | //int primCount = 0; |
154 | //SceneObjectGroup obj = null; | 127 | //SceneObjectGroup obj = null; |
155 | 128 | ||
156 | if(File.Exists(filename)) | 129 | if(File.Exists(filename)) |
157 | { | 130 | { |
158 | XmlTextReader reader = new XmlTextReader(filename); | 131 | XmlTextReader reader = new XmlTextReader(filename); |
159 | reader.WhitespaceHandling = WhitespaceHandling.None; | 132 | reader.WhitespaceHandling = WhitespaceHandling.None; |
@@ -162,99 +135,153 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
162 | rootNode = doc.FirstChild; | 135 | rootNode = doc.FirstChild; |
163 | foreach (XmlNode aPrimNode in rootNode.ChildNodes) | 136 | foreach (XmlNode aPrimNode in rootNode.ChildNodes) |
164 | { | 137 | { |
165 | objectList.Add(aPrimNode.OuterXml); | 138 | objectList.Add(aPrimNode.OuterXml); |
166 | } | 139 | } |
167 | return objectList; | 140 | return objectList; |
168 | } | 141 | } |
169 | return null; | 142 | return null; |
170 | } | 143 | } |
171 | 144 | ||
172 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid) | 145 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid) |
173 | { | 146 | { |
174 | int revision = NumOfRegionRev(regionid); | 147 | int revision = NumOfRegionRev(regionid); |
175 | m_log.Info("[FSDB]: found revisions:" + revision); | 148 | m_log.Info("[FSDB]: found revisions:" + revision); |
176 | System.Collections.ArrayList xmlList = new System.Collections.ArrayList(); | 149 | System.Collections.ArrayList xmlList = new System.Collections.ArrayList(); |
177 | string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + | 150 | string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + |
178 | + revision + Slash.DirectorySeparatorChar + "objects.xml"; | 151 | + revision + Slash.DirectorySeparatorChar + "objects.xml"; |
179 | XmlDocument doc = new XmlDocument(); | 152 | XmlDocument doc = new XmlDocument(); |
180 | XmlNode rootNode; | 153 | XmlNode rootNode; |
181 | 154 | ||
182 | 155 | ||
183 | m_log.Info("[FSDB]: Checking if " + filename + " exists."); | 156 | m_log.Info("[FSDB]: Checking if " + filename + " exists."); |
184 | if(File.Exists(filename)) | 157 | if(File.Exists(filename)) |
185 | { | 158 | { |
186 | Stopwatch x = new Stopwatch(); | 159 | Stopwatch x = new Stopwatch(); |
187 | x.Start(); | 160 | x.Start(); |
188 | 161 | ||
189 | XmlTextReader reader = new XmlTextReader(filename); | 162 | XmlTextReader reader = new XmlTextReader(filename); |
190 | reader.WhitespaceHandling = WhitespaceHandling.None; | 163 | reader.WhitespaceHandling = WhitespaceHandling.None; |
191 | doc.Load(reader); | 164 | doc.Load(reader); |
192 | reader.Close(); | 165 | reader.Close(); |
193 | rootNode = doc.FirstChild; | 166 | rootNode = doc.FirstChild; |
194 | 167 | ||
195 | foreach (XmlNode aPrimNode in rootNode.ChildNodes) | 168 | foreach (XmlNode aPrimNode in rootNode.ChildNodes) |
196 | xmlList.Add(aPrimNode.OuterXml); | 169 | xmlList.Add(aPrimNode.OuterXml); |
197 | 170 | ||
198 | x.Stop(); | 171 | x.Stop(); |
199 | TimeToDownload += x.ElapsedMilliseconds; | 172 | TimeToDownload += x.ElapsedMilliseconds; |
200 | m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload); | 173 | m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload); |
201 | 174 | ||
202 | return xmlList; | 175 | return xmlList; |
203 | } | 176 | } |
204 | return null; | 177 | return null; |
205 | } | 178 | } |
206 | 179 | ||
207 | public string GetRegionObjectHeightMap(LLUUID regionid) | 180 | public void Initialise(Scene scene, string dir) |
208 | { | 181 | { |
209 | String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + | 182 | lock(this) |
210 | Slash.DirectorySeparatorChar + "heightmap.r32"; | 183 | { |
211 | FileStream fs = new FileStream( filename, FileMode.Open); | 184 | if (m_repodir == null) |
212 | StreamReader sr = new StreamReader(fs); | 185 | m_repodir = dir; |
213 | String result = sr.ReadToEnd(); | 186 | } |
214 | sr.Close(); | 187 | lock(m_scenes) |
215 | fs.Close(); | 188 | m_scenes.Add(scene.RegionInfo.RegionID, scene); |
216 | return result; | 189 | } |
217 | } | 190 | |
218 | 191 | public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID regionid) | |
219 | public string GetRegionObjectHeightMap(LLUUID regionid, int revision) | 192 | { |
220 | { | 193 | SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>(); |
221 | String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + | 194 | |
222 | Slash.DirectorySeparatorChar + "heightmap.r32"; | 195 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; |
223 | FileStream fs = new FileStream( filename, FileMode.Open); | 196 | string[] directories = Directory.GetDirectories(scenedir); |
224 | StreamReader sr = new StreamReader(fs); | 197 | |
225 | String result = sr.ReadToEnd(); | 198 | FileStream fs = null; |
226 | sr.Close(); | 199 | StreamReader sr = null; |
227 | fs.Close(); | 200 | String logMessage = ""; |
228 | return result; | 201 | String logLocation = ""; |
229 | } | 202 | foreach(string revisionDir in directories) |
230 | 203 | { | |
231 | public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID regionid) | 204 | try { |
232 | { | 205 | logLocation = revisionDir + Slash.DirectorySeparatorChar + "log"; |
233 | SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>(); | 206 | fs = new FileStream( logLocation, FileMode.Open); |
234 | 207 | sr = new StreamReader(fs); | |
235 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | 208 | logMessage = sr.ReadToEnd(); |
236 | string[] directories = Directory.GetDirectories(scenedir); | 209 | sr.Close(); |
237 | 210 | fs.Close(); | |
238 | FileStream fs = null; | 211 | revisionDict.Add(revisionDir, logMessage); |
239 | StreamReader sr = null; | 212 | } |
240 | String logMessage = ""; | 213 | catch (Exception) |
241 | String logLocation = ""; | 214 | {} |
242 | foreach(string revisionDir in directories) | 215 | } |
243 | { | 216 | |
244 | try { | 217 | return revisionDict; |
245 | logLocation = revisionDir + Slash.DirectorySeparatorChar + "log"; | 218 | } |
246 | fs = new FileStream( logLocation, FileMode.Open); | 219 | |
247 | sr = new StreamReader(fs); | 220 | public int NumOfRegionRev(LLUUID regionid) |
248 | logMessage = sr.ReadToEnd(); | 221 | { |
249 | sr.Close(); | 222 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; |
250 | fs.Close(); | 223 | m_log.Info("[FSDB]: Reading scene dir: " + scenedir); |
251 | revisionDict.Add(revisionDir, logMessage); | 224 | string[] directories = Directory.GetDirectories(scenedir); |
252 | } | 225 | return directories.Length; |
253 | catch (Exception) | 226 | } |
254 | {} | 227 | |
255 | } | 228 | // Run once and only once. |
256 | 229 | public void PostInitialise() | |
257 | return revisionDict; | 230 | { |
258 | } | 231 | SetupSerialiser(); |
259 | } | 232 | |
260 | } | 233 | m_log.Info("[FSDB]: Creating repository in " + m_repodir + "."); |
234 | CreateDirectory(); | ||
235 | } | ||
236 | |||
237 | public void SaveRegion(LLUUID regionid, string regionName, string logMessage) | ||
238 | { | ||
239 | m_log.Info("[FSDB]: ..............................."); | ||
240 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | ||
241 | |||
242 | m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir); | ||
243 | if (!Directory.Exists(scenedir)) | ||
244 | Directory.CreateDirectory(scenedir); | ||
245 | |||
246 | int newRevisionNum = GetMostRecentRevision(regionid)+1; | ||
247 | string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar; | ||
248 | |||
249 | m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir); | ||
250 | if (!Directory.Exists(revisiondir)) | ||
251 | Directory.CreateDirectory(revisiondir); | ||
252 | |||
253 | try { | ||
254 | Stopwatch x = new Stopwatch(); | ||
255 | x.Start(); | ||
256 | if (m_scenes.ContainsKey(regionid)) | ||
257 | { | ||
258 | m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir); | ||
259 | } | ||
260 | x.Stop(); | ||
261 | TimeToSave += x.ElapsedMilliseconds; | ||
262 | m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds); | ||
263 | m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave); | ||
264 | } | ||
265 | catch (Exception e) | ||
266 | { | ||
267 | m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e); | ||
268 | return; | ||
269 | } | ||
270 | |||
271 | try { | ||
272 | // Finish by writing log message. | ||
273 | FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite); | ||
274 | StreamWriter sw = new StreamWriter(file); | ||
275 | sw.Write(logMessage); | ||
276 | sw.Close(); | ||
277 | } | ||
278 | catch (Exception e) | ||
279 | { | ||
280 | m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e); | ||
281 | return; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | #endregion Public Methods | ||
286 | } | ||
287 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs index e337482..5e85b2e 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs | |||
@@ -1,130 +1,142 @@ | |||
1 | #region Header | ||
2 | |||
1 | // GitDatabase.cs | 3 | // GitDatabase.cs |
2 | // | 4 | // |
3 | // | 5 | // |
4 | // | 6 | // |
5 | 7 | ||
8 | #endregion Header | ||
9 | |||
6 | using System; | 10 | using System; |
7 | using System.Collections.Generic; | 11 | using System.Collections.Generic; |
8 | using System.IO; | 12 | using System.IO; |
13 | using Slash = System.IO.Path; | ||
9 | using System.Reflection; | 14 | using System.Reflection; |
10 | using System.Xml; | 15 | using System.Xml; |
16 | |||
11 | using libsecondlife; | 17 | using libsecondlife; |
18 | |||
12 | using Nini.Config; | 19 | using Nini.Config; |
20 | |||
13 | using OpenSim.Framework; | 21 | using OpenSim.Framework; |
14 | using OpenSim.Region.Environment.Interfaces; | 22 | using OpenSim.Region.Environment.Interfaces; |
15 | using OpenSim.Region.Environment.Modules.World.Serialiser; | 23 | using OpenSim.Region.Environment.Modules.World.Serialiser; |
16 | using OpenSim.Region.Environment.Modules.World.Terrain; | 24 | using OpenSim.Region.Environment.Modules.World.Terrain; |
17 | using OpenSim.Region.Environment.Scenes; | 25 | using OpenSim.Region.Environment.Scenes; |
18 | using log4net; | ||
19 | using OpenSim.Region.Physics.Manager; | 26 | using OpenSim.Region.Physics.Manager; |
27 | |||
28 | using log4net; | ||
29 | |||
20 | using Axiom.Math; | 30 | using Axiom.Math; |
21 | using Slash=System.IO.Path; | ||
22 | 31 | ||
23 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 32 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
24 | { | 33 | { |
25 | 34 | /// <summary> | |
26 | /// <summary> | 35 | /// Just a stub :-( |
27 | /// Just a stub :-( | 36 | /// </summary> |
28 | /// </summary> | 37 | public class GitDatabase : IContentDatabase |
29 | public class GitDatabase : IContentDatabase | 38 | { |
30 | { | 39 | #region Constructors |
31 | 40 | ||
32 | public GitDatabase() | 41 | public GitDatabase() |
33 | { | 42 | { |
34 | } | 43 | } |
35 | 44 | ||
36 | public void Initialise(Scene scene, String dir) | 45 | #endregion Constructors |
37 | { | 46 | |
38 | 47 | #region Public Methods | |
39 | } | 48 | |
40 | 49 | public SceneObjectGroup GetMostRecentObjectRevision(LLUUID id) | |
41 | public void PostInitialise() | 50 | { |
42 | { | 51 | return null; |
43 | 52 | } | |
44 | } | 53 | |
45 | 54 | public int GetMostRecentRevision(LLUUID regionid) | |
46 | public int NumOfObjectRev(LLUUID id) | 55 | { |
47 | { | 56 | return 0; |
48 | return 0; | 57 | } |
49 | } | 58 | |
50 | 59 | public SceneObjectGroup GetObjectRevision(LLUUID id, int revision) | |
51 | public int NumOfRegionRev(LLUUID regionid) | 60 | { |
52 | { | 61 | return null; |
53 | return 0; | 62 | } |
54 | } | 63 | |
55 | 64 | public System.Collections.ArrayList GetObjectsFromRegion(LLUUID regionid, int revision) | |
56 | public bool InRepository(LLUUID id) | 65 | { |
57 | { | 66 | return null; |
58 | return false; | 67 | } |
59 | } | 68 | |
60 | 69 | public string GetRegionObjectHeightMap(LLUUID regionid) | |
61 | public void SaveRegion(LLUUID regionid, string regionName, string logMessage) | 70 | { |
62 | { | 71 | return null; |
63 | 72 | } | |
64 | } | 73 | |
65 | 74 | public string GetRegionObjectHeightMap(LLUUID regionid, int revision) | |
66 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid) | 75 | { |
67 | { | 76 | return null; |
68 | return null; | 77 | } |
69 | } | 78 | |
70 | 79 | public string GetRegionObjectXML(LLUUID regionid) | |
71 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision) | 80 | { |
72 | { | 81 | return null; |
73 | return null; | 82 | } |
74 | } | 83 | |
75 | 84 | public string GetRegionObjectXML(LLUUID regionid, int revision) | |
76 | public string GetRegionObjectXML(LLUUID regionid) | 85 | { |
77 | { | 86 | return null; |
78 | return null; | 87 | } |
79 | } | 88 | |
80 | 89 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid) | |
81 | public string GetRegionObjectXML(LLUUID regionid, int revision) | 90 | { |
82 | { | 91 | return null; |
83 | return null; | 92 | } |
84 | } | 93 | |
85 | 94 | public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision) | |
86 | public string GetRegionObjectHeightMap(LLUUID regionid) | 95 | { |
87 | { | 96 | return null; |
88 | return null; | 97 | } |
89 | } | 98 | |
90 | 99 | public bool InRepository(LLUUID id) | |
91 | public string GetRegionObjectHeightMap(LLUUID regionid, int revision) | 100 | { |
92 | { | 101 | return false; |
93 | return null; | 102 | } |
94 | } | 103 | |
95 | 104 | public void Initialise(Scene scene, String dir) | |
96 | public System.Collections.ArrayList GetObjectsFromRegion(LLUUID regionid, int revision) | 105 | { |
97 | { | 106 | } |
98 | return null; | 107 | |
99 | } | 108 | public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(LLUUID id) |
100 | 109 | { | |
101 | public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id) | 110 | return null; |
102 | { | 111 | } |
103 | return null; | 112 | |
104 | } | 113 | public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id) |
105 | 114 | { | |
106 | public void SaveObject(SceneObjectGroup entity) | 115 | return null; |
107 | { | 116 | } |
108 | } | 117 | |
109 | 118 | public int NumOfObjectRev(LLUUID id) | |
110 | public SceneObjectGroup GetMostRecentObjectRevision(LLUUID id) | 119 | { |
111 | { | 120 | return 0; |
112 | return null; | 121 | } |
113 | } | 122 | |
114 | 123 | public int NumOfRegionRev(LLUUID regionid) | |
115 | public SceneObjectGroup GetObjectRevision(LLUUID id, int revision) | 124 | { |
116 | { | 125 | return 0; |
117 | return null; | 126 | } |
118 | } | 127 | |
119 | 128 | public void PostInitialise() | |
120 | public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(LLUUID id) | 129 | { |
121 | { | 130 | } |
122 | return null; | 131 | |
123 | } | 132 | public void SaveObject(SceneObjectGroup entity) |
124 | 133 | { | |
125 | public int GetMostRecentRevision(LLUUID regionid) | 134 | } |
126 | { | 135 | |
127 | return 0; | 136 | public void SaveRegion(LLUUID regionid, string regionName, string logMessage) |
128 | } | 137 | { |
129 | } | 138 | } |
130 | } | 139 | |
140 | #endregion Public Methods | ||
141 | } | ||
142 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs index f37f95d..1d81978 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs | |||
@@ -1,57 +1,70 @@ | |||
1 | #region Header | ||
2 | |||
1 | // IContentDatabase.cs | 3 | // IContentDatabase.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | // | 5 | // |
4 | // | 6 | // |
5 | // | 7 | // |
6 | 8 | ||
9 | #endregion Header | ||
10 | |||
7 | using System; | 11 | using System; |
12 | |||
8 | using libsecondlife; | 13 | using libsecondlife; |
14 | |||
9 | using OpenSim.Region.Environment.Scenes; | 15 | using OpenSim.Region.Environment.Scenes; |
16 | |||
10 | using Nini.Config; | 17 | using Nini.Config; |
11 | 18 | ||
12 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 19 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
13 | { | 20 | { |
14 | public interface IContentDatabase | 21 | public interface IContentDatabase |
15 | { | 22 | { |
16 | /// <summary> | 23 | #region Methods |
17 | /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database. | 24 | |
18 | /// Initialise should be called one for each region to be contained in the database. The directory should be the full path | 25 | /// <summary> |
19 | /// to the repository and will only be defined once, regardless of how many times the method is called. | 26 | /// Returns the most recent revision number of a region. |
20 | /// </summary> | 27 | /// </summary> |
21 | void Initialise(Scene scene, String dir); | 28 | int GetMostRecentRevision(LLUUID regionid); |
22 | 29 | ||
23 | /// <summary> | 30 | string GetRegionObjectHeightMap(LLUUID regionid); |
24 | /// Should be called once after Initialise has been called. | 31 | |
25 | /// </summary> | 32 | string GetRegionObjectHeightMap(LLUUID regionid, int revision); |
26 | void PostInitialise(); | 33 | |
27 | 34 | /// <summary> | |
28 | /// <summary> | 35 | /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region. |
29 | /// Returns the total number of revisions saved for a specific region. | 36 | /// </summary> |
30 | /// </summary> | 37 | System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid); |
31 | int NumOfRegionRev(LLUUID regionid); | 38 | |
32 | 39 | System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision); | |
33 | /// <summary> | 40 | |
34 | /// Saves the Region terrain map and objects within the region as xml to the database. | 41 | /// <summary> |
35 | /// </summary> | 42 | /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database. |
36 | void SaveRegion(LLUUID regionid, string regionName, string logMessage); | 43 | /// Initialise should be called one for each region to be contained in the database. The directory should be the full path |
37 | 44 | /// to the repository and will only be defined once, regardless of how many times the method is called. | |
38 | /// <summary> | 45 | /// </summary> |
39 | /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region. | 46 | void Initialise(Scene scene, String dir); |
40 | /// </summary> | 47 | |
41 | System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid); | 48 | /// <summary> |
42 | System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision); | 49 | /// Returns a list of the revision numbers and corresponding log messages for a given region. |
43 | 50 | /// </summary> | |
44 | string GetRegionObjectHeightMap(LLUUID regionid); | 51 | System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id); |
45 | string GetRegionObjectHeightMap(LLUUID regionid, int revision); | 52 | |
46 | 53 | /// <summary> | |
47 | /// <summary> | 54 | /// Returns the total number of revisions saved for a specific region. |
48 | /// Returns a list of the revision numbers and corresponding log messages for a given region. | 55 | /// </summary> |
49 | /// </summary> | 56 | int NumOfRegionRev(LLUUID regionid); |
50 | System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id); | 57 | |
51 | 58 | /// <summary> | |
52 | /// <summary> | 59 | /// Should be called once after Initialise has been called. |
53 | /// Returns the most recent revision number of a region. | 60 | /// </summary> |
54 | /// </summary> | 61 | void PostInitialise(); |
55 | int GetMostRecentRevision(LLUUID regionid); | 62 | |
56 | } | 63 | /// <summary> |
57 | } | 64 | /// Saves the Region terrain map and objects within the region as xml to the database. |
65 | /// </summary> | ||
66 | void SaveRegion(LLUUID regionid, string regionName, string logMessage); | ||
67 | |||
68 | #endregion Methods | ||
69 | } | ||
70 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs index f0763d3..c203054 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs | |||
@@ -1,219 +1,256 @@ | |||
1 | #region Header | ||
2 | |||
1 | // MetaEntity.cs | 3 | // MetaEntity.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | // | 5 | // |
4 | // TODO: | 6 | // TODO: |
5 | // Create a physics manager to the meta object if there isn't one or the object knows of no scene but the user wants physics enabled. | 7 | // Create a physics manager to the meta object if there isn't one or the object knows of no scene but the user wants physics enabled. |
6 | 8 | ||
9 | #endregion Header | ||
7 | 10 | ||
8 | using System; | 11 | using System; |
9 | using System.Collections.Generic; | 12 | using System.Collections.Generic; |
10 | using System.Drawing; | 13 | using System.Drawing; |
14 | |||
11 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
12 | using Nini.Config; | 17 | using Nini.Config; |
18 | |||
13 | using OpenSim.Framework; | 19 | using OpenSim.Framework; |
14 | using OpenSim.Region.Environment.Interfaces; | 20 | using OpenSim.Region.Environment.Interfaces; |
15 | using OpenSim.Region.Environment.Scenes; | 21 | using OpenSim.Region.Environment.Scenes; |
16 | using log4net; | ||
17 | using OpenSim.Region.Physics.Manager; | 22 | using OpenSim.Region.Physics.Manager; |
23 | |||
24 | using log4net; | ||
25 | |||
18 | using Axiom.Math; | 26 | using Axiom.Math; |
19 | 27 | ||
20 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 28 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
21 | { | 29 | { |
22 | public class MetaEntity | 30 | public class MetaEntity |
23 | { | 31 | { |
24 | protected static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 32 | #region Constants |
25 | 33 | ||
26 | protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity. | 34 | public const float INVISIBLE = .95f; |
27 | protected uint m_metaLocalid; | 35 | |
28 | 36 | // Settings for transparency of metaentity | |
29 | // Settings for transparency of metaentity | 37 | public const float NONE = 0f; |
30 | public const float NONE = 0f; | 38 | public const float TRANSLUCENT = .5f; |
31 | public const float TRANSLUCENT = .5f; | 39 | |
32 | public const float INVISIBLE = .95f; | 40 | #endregion Constants |
33 | 41 | ||
34 | public Scene Scene | 42 | #region Static Fields |
35 | { | 43 | |
36 | get { return m_Entity.Scene; } | 44 | protected static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
37 | } | 45 | |
38 | 46 | #endregion Static Fields | |
39 | public SceneObjectPart RootPart | 47 | |
40 | { | 48 | #region Fields |
41 | get { return m_Entity.RootPart; } | 49 | |
42 | set { m_Entity.RootPart = value; } | 50 | protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity. |
43 | } | 51 | protected uint m_metaLocalid; |
44 | 52 | ||
45 | public LLUUID UUID | 53 | #endregion Fields |
46 | { | 54 | |
47 | get { return m_Entity.UUID; } | 55 | #region Constructors |
48 | set { m_Entity.UUID = value; } | 56 | |
49 | } | 57 | public MetaEntity() |
50 | 58 | { | |
51 | public uint LocalId | 59 | } |
52 | { | 60 | |
53 | get { return m_Entity.LocalId; } | 61 | /// <summary> |
54 | set { m_Entity.LocalId = value; } | 62 | /// Makes a new meta entity by copying the given scene object group. |
55 | } | 63 | /// The physics boolean is just a stub right now. |
56 | 64 | /// </summary> | |
57 | public SceneObjectGroup ObjectGroup | 65 | public MetaEntity(SceneObjectGroup orig, bool physics) |
58 | { | 66 | { |
59 | get { return m_Entity; } | 67 | m_Entity = orig.Copy(orig.RootPart.OwnerID, orig.RootPart.GroupID, false); |
60 | } | 68 | Initialize(physics); |
61 | 69 | } | |
62 | public Dictionary<LLUUID, SceneObjectPart> Children | 70 | |
63 | { | 71 | /// <summary> |
64 | get { return m_Entity.Children; } | 72 | /// Takes an XML description of a scene object group and converts it to a meta entity. |
65 | set { m_Entity.Children = value; } | 73 | /// </summary> |
66 | } | 74 | public MetaEntity(string objectXML, Scene scene, bool physics) |
67 | 75 | { | |
68 | public int PrimCount | 76 | m_Entity = new SceneObjectGroup(objectXML); |
69 | { | 77 | m_Entity.SetScene(scene); |
70 | get { return m_Entity.PrimCount; } | 78 | Initialize(physics); |
71 | } | 79 | } |
72 | 80 | ||
73 | public MetaEntity() | 81 | #endregion Constructors |
74 | { | 82 | |
75 | } | 83 | #region Public Properties |
76 | 84 | ||
77 | /// <summary> | 85 | public Dictionary<LLUUID, SceneObjectPart> Children |
78 | /// Makes a new meta entity by copying the given scene object group. | 86 | { |
79 | /// The physics boolean is just a stub right now. | 87 | get { return m_Entity.Children; } |
80 | /// </summary> | 88 | set { m_Entity.Children = value; } |
81 | public MetaEntity(SceneObjectGroup orig, bool physics) | 89 | } |
82 | { | 90 | |
83 | m_Entity = orig.Copy(orig.RootPart.OwnerID, orig.RootPart.GroupID, false); | 91 | public uint LocalId |
84 | Initialize(physics); | 92 | { |
85 | } | 93 | get { return m_Entity.LocalId; } |
86 | 94 | set { m_Entity.LocalId = value; } | |
87 | /// <summary> | 95 | } |
88 | /// Takes an XML description of a scene object group and converts it to a meta entity. | 96 | |
89 | /// </summary> | 97 | public SceneObjectGroup ObjectGroup |
90 | public MetaEntity(string objectXML, Scene scene, bool physics) | 98 | { |
91 | { | 99 | get { return m_Entity; } |
92 | m_Entity = new SceneObjectGroup(objectXML); | 100 | } |
93 | m_Entity.SetScene(scene); | 101 | |
94 | Initialize(physics); | 102 | public int PrimCount |
95 | } | 103 | { |
96 | 104 | get { return m_Entity.PrimCount; } | |
97 | // The metaentity objectgroup must have unique localids as well as unique uuids. | 105 | } |
98 | // localids are used by the client to refer to parts. | 106 | |
99 | // uuids are sent to the client and back to the server to identify parts on the server side. | 107 | public SceneObjectPart RootPart |
100 | /// <summary> | 108 | { |
101 | /// Changes localids and uuids of m_Entity. | 109 | get { return m_Entity.RootPart; } |
102 | /// </summary> | 110 | set { m_Entity.RootPart = value; } |
103 | protected void Initialize(bool physics) | 111 | } |
104 | { | 112 | |
105 | //make new uuids | 113 | public Scene Scene |
106 | Dictionary<LLUUID, SceneObjectPart> parts = new Dictionary<LLUUID, SceneObjectPart>(); | 114 | { |
107 | foreach(SceneObjectPart part in m_Entity.Children.Values) | 115 | get { return m_Entity.Scene; } |
108 | { | 116 | } |
109 | part.ResetIDs(part.LinkNum); | 117 | |
110 | parts.Add(part.UUID, part); | 118 | public LLUUID UUID |
111 | } | 119 | { |
112 | 120 | get { return m_Entity.UUID; } | |
113 | // make new localids | 121 | set { m_Entity.UUID = value; } |
114 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 122 | } |
115 | part.LocalId = m_Entity.Scene.PrimIDAllocate(); | 123 | |
116 | 124 | #endregion Public Properties | |
117 | //finalize | 125 | |
118 | m_Entity.UpdateParentIDs(); | 126 | #region Protected Methods |
119 | m_Entity.RootPart.PhysActor = null; | 127 | |
120 | m_Entity.Children = parts; | 128 | // The metaentity objectgroup must have unique localids as well as unique uuids. |
121 | 129 | // localids are used by the client to refer to parts. | |
122 | } | 130 | // uuids are sent to the client and back to the server to identify parts on the server side. |
123 | 131 | /// <summary> | |
124 | public void SendFullUpdate(IClientAPI client) | 132 | /// Changes localids and uuids of m_Entity. |
125 | { | 133 | /// </summary> |
126 | // Not sure what clientFlags should be but 0 seems to work | 134 | protected void Initialize(bool physics) |
127 | SendFullUpdate(client, 0); | 135 | { |
128 | } | 136 | //make new uuids |
129 | public void SendFullUpdateToAll() | 137 | Dictionary<LLUUID, SceneObjectPart> parts = new Dictionary<LLUUID, SceneObjectPart>(); |
130 | { | 138 | foreach(SceneObjectPart part in m_Entity.Children.Values) |
131 | uint clientFlags = 0; | 139 | { |
132 | m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) | 140 | part.ResetIDs(part.LinkNum); |
133 | { m_Entity.SendFullUpdateToClient(controller, clientFlags); } | 141 | parts.Add(part.UUID, part); |
134 | ); | 142 | } |
135 | } | 143 | |
136 | 144 | // make new localids | |
137 | public void SendFullUpdate(IClientAPI client, uint clientFlags) | 145 | foreach (SceneObjectPart part in m_Entity.Children.Values) |
138 | { | 146 | part.LocalId = m_Entity.Scene.PrimIDAllocate(); |
139 | m_Entity.SendFullUpdateToClient(client, clientFlags); | 147 | |
140 | } | 148 | //finalize |
141 | 149 | m_Entity.UpdateParentIDs(); | |
142 | /// <summary> | 150 | m_Entity.RootPart.PhysActor = null; |
143 | /// Hides the metaentity from a single client. | 151 | m_Entity.Children = parts; |
144 | /// </summary> | 152 | } |
145 | public virtual void Hide(IClientAPI client) | 153 | |
146 | { | 154 | #endregion Protected Methods |
147 | //This deletes the group without removing from any databases. | 155 | |
148 | //This is important because we are not IN any database. | 156 | #region Public Methods |
149 | //m_Entity.FakeDeleteGroup(); | 157 | |
150 | foreach( SceneObjectPart part in m_Entity.Children.Values) | 158 | /// <summary> |
151 | client.SendKillObject(m_Entity.RegionHandle, part.LocalId); | 159 | /// Hides the metaentity from a single client. |
152 | } | 160 | /// </summary> |
153 | 161 | public virtual void Hide(IClientAPI client) | |
154 | /// <summary> | 162 | { |
155 | /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server. | 163 | //This deletes the group without removing from any databases. |
156 | /// </summary> | 164 | //This is important because we are not IN any database. |
157 | public virtual void HideFromAll() | 165 | //m_Entity.FakeDeleteGroup(); |
158 | { | 166 | foreach( SceneObjectPart part in m_Entity.Children.Values) |
159 | foreach( SceneObjectPart part in m_Entity.Children.Values) | 167 | client.SendKillObject(m_Entity.RegionHandle, part.LocalId); |
160 | m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) | 168 | } |
161 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } | 169 | |
162 | ); | 170 | /// <summary> |
163 | } | 171 | /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server. |
164 | 172 | /// </summary> | |
165 | /// <summary> | 173 | public virtual void HideFromAll() |
166 | /// Makes a single SceneObjectPart see through. | 174 | { |
167 | /// </summary> | 175 | foreach( SceneObjectPart part in m_Entity.Children.Values) |
168 | /// <param name="part"> | 176 | m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) |
169 | /// A <see cref="SceneObjectPart"/> | 177 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } |
170 | /// The part to make see through | 178 | ); |
171 | /// </param> | 179 | } |
172 | /// <param name="transparencyAmount"> | 180 | |
173 | /// A <see cref="System.Single"/> | 181 | public void SendFullUpdate(IClientAPI client) |
174 | /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible. | 182 | { |
175 | /// </param> | 183 | // Not sure what clientFlags should be but 0 seems to work |
176 | public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount) | 184 | SendFullUpdate(client, 0); |
177 | { | 185 | } |
178 | LLObject.TextureEntry tex = null; | 186 | |
179 | LLColor texcolor; | 187 | public void SendFullUpdate(IClientAPI client, uint clientFlags) |
180 | try | 188 | { |
181 | { | 189 | m_Entity.SendFullUpdateToClient(client, clientFlags); |
182 | tex = part.Shape.Textures; | 190 | } |
183 | texcolor = new LLColor(); | 191 | |
184 | } | 192 | public void SendFullUpdateToAll() |
185 | catch(Exception) | 193 | { |
186 | { | 194 | uint clientFlags = 0; |
187 | //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e); | 195 | m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) |
188 | return; | 196 | { m_Entity.SendFullUpdateToClient(controller, clientFlags); } |
189 | } | 197 | ); |
190 | 198 | } | |
191 | for (uint i = 0; i < tex.FaceTextures.Length; i++) | 199 | |
192 | { | 200 | /// <summary> |
193 | try { | 201 | /// Makes a single SceneObjectPart see through. |
194 | if (tex.FaceTextures[i] != null) | 202 | /// </summary> |
195 | { | 203 | /// <param name="part"> |
196 | texcolor = tex.FaceTextures[i].RGBA; | 204 | /// A <see cref="SceneObjectPart"/> |
197 | texcolor.A = transparencyAmount; | 205 | /// The part to make see through |
198 | tex.FaceTextures[i].RGBA = texcolor; | 206 | /// </param> |
199 | } | 207 | /// <param name="transparencyAmount"> |
200 | } | 208 | /// A <see cref="System.Single"/> |
201 | catch (Exception) | 209 | /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible. |
202 | { | 210 | /// </param> |
203 | //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e); | 211 | public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount) |
204 | continue; | 212 | { |
205 | } | 213 | LLObject.TextureEntry tex = null; |
206 | } | 214 | LLColor texcolor; |
207 | try { | 215 | try |
208 | texcolor = tex.DefaultTexture.RGBA; | 216 | { |
209 | texcolor.A = transparencyAmount; | 217 | tex = part.Shape.Textures; |
210 | tex.DefaultTexture.RGBA = texcolor; | 218 | texcolor = new LLColor(); |
211 | part.Shape.TextureEntry = tex.ToBytes(); | 219 | } |
212 | } | 220 | catch(Exception) |
213 | catch (Exception) | 221 | { |
214 | { | 222 | //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e); |
215 | //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e); | 223 | return; |
216 | } | 224 | } |
217 | } | 225 | |
218 | } | 226 | for (uint i = 0; i < tex.FaceTextures.Length; i++) |
227 | { | ||
228 | try { | ||
229 | if (tex.FaceTextures[i] != null) | ||
230 | { | ||
231 | texcolor = tex.FaceTextures[i].RGBA; | ||
232 | texcolor.A = transparencyAmount; | ||
233 | tex.FaceTextures[i].RGBA = texcolor; | ||
234 | } | ||
235 | } | ||
236 | catch (Exception) | ||
237 | { | ||
238 | //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e); | ||
239 | continue; | ||
240 | } | ||
241 | } | ||
242 | try { | ||
243 | texcolor = tex.DefaultTexture.RGBA; | ||
244 | texcolor.A = transparencyAmount; | ||
245 | tex.DefaultTexture.RGBA = texcolor; | ||
246 | part.Shape.TextureEntry = tex.ToBytes(); | ||
247 | } | ||
248 | catch (Exception) | ||
249 | { | ||
250 | //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | #endregion Public Methods | ||
255 | } | ||
219 | } \ No newline at end of file | 256 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs index 55365ac..bfa7e5d 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs | |||
@@ -1,81 +1,97 @@ | |||
1 | #region Header | ||
2 | |||
1 | // PointMetaEntity.cs created with MonoDevelop | 3 | // PointMetaEntity.cs created with MonoDevelop |
2 | // User: bongiojp at 3:03 PM 8/6/2008 | 4 | // User: bongiojp at 3:03 PM 8/6/2008 |
3 | // | 5 | // |
4 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers | 6 | // To change standard headers go to Edit->Preferences->Coding->Standard Headers |
5 | // | 7 | // |
6 | 8 | ||
9 | #endregion Header | ||
10 | |||
7 | using System; | 11 | using System; |
8 | using System.Collections.Generic; | 12 | using System.Collections.Generic; |
9 | using System.Drawing; | 13 | using System.Drawing; |
14 | |||
10 | using libsecondlife; | 15 | using libsecondlife; |
16 | |||
11 | using Nini.Config; | 17 | using Nini.Config; |
18 | |||
12 | using OpenSim.Framework; | 19 | using OpenSim.Framework; |
13 | using OpenSim.Region.Environment.Interfaces; | 20 | using OpenSim.Region.Environment.Interfaces; |
14 | using OpenSim.Region.Environment.Scenes; | 21 | using OpenSim.Region.Environment.Scenes; |
15 | using log4net; | ||
16 | using OpenSim.Region.Physics.Manager; | 22 | using OpenSim.Region.Physics.Manager; |
23 | |||
24 | using log4net; | ||
25 | |||
17 | using Axiom.Math; | 26 | using Axiom.Math; |
18 | 27 | ||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 28 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
20 | { | 29 | { |
21 | 30 | public class PointMetaEntity : MetaEntity | |
22 | 31 | { | |
23 | public class PointMetaEntity : MetaEntity | 32 | #region Constructors |
24 | { | 33 | |
25 | 34 | public PointMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency) | |
26 | public PointMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency) : base() | 35 | : base() |
27 | { | 36 | { |
28 | CreatePointEntity(scene, LLUUID.Random(), LocalId, groupPos); | 37 | CreatePointEntity(scene, LLUUID.Random(), LocalId, groupPos); |
29 | SetPartTransparency(m_Entity.RootPart, transparency); | 38 | SetPartTransparency(m_Entity.RootPart, transparency); |
30 | } | 39 | } |
31 | 40 | ||
32 | public PointMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency) : base() | 41 | public PointMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency) |
33 | { | 42 | : base() |
34 | CreatePointEntity(scene, uuid, LocalId, groupPos); | 43 | { |
35 | SetPartTransparency(m_Entity.RootPart, transparency); | 44 | CreatePointEntity(scene, uuid, LocalId, groupPos); |
36 | } | 45 | SetPartTransparency(m_Entity.RootPart, transparency); |
37 | 46 | } | |
38 | private void CreatePointEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos) | 47 | |
39 | { | 48 | #endregion Constructors |
40 | SceneObjectGroup x = new SceneObjectGroup(); | 49 | |
41 | SceneObjectPart y = new SceneObjectPart(); | 50 | #region Private Methods |
42 | 51 | ||
43 | //Initialize part | 52 | private void CreatePointEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos) |
44 | y.Name = "Very Small Point"; | 53 | { |
54 | SceneObjectGroup x = new SceneObjectGroup(); | ||
55 | SceneObjectPart y = new SceneObjectPart(); | ||
56 | |||
57 | //Initialize part | ||
58 | y.Name = "Very Small Point"; | ||
45 | y.RegionHandle = scene.RegionInfo.RegionHandle; | 59 | y.RegionHandle = scene.RegionInfo.RegionHandle; |
46 | y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; | 60 | y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; |
47 | y.OwnerID = LLUUID.Zero; | 61 | y.OwnerID = LLUUID.Zero; |
48 | y.CreatorID = LLUUID.Zero; | 62 | y.CreatorID = LLUUID.Zero; |
49 | y.LastOwnerID = LLUUID.Zero; | 63 | y.LastOwnerID = LLUUID.Zero; |
50 | y.UUID = uuid; | 64 | y.UUID = uuid; |
51 | 65 | ||
52 | y.LocalId = LocalId; | 66 | y.LocalId = LocalId; |
53 | 67 | ||
54 | y.Shape = PrimitiveBaseShape.CreateBox(); | 68 | y.Shape = PrimitiveBaseShape.CreateBox(); |
55 | y.Scale = new LLVector3(0.01f,0.01f,0.01f); | 69 | y.Scale = new LLVector3(0.01f,0.01f,0.01f); |
56 | y.LastOwnerID = LLUUID.Zero; | 70 | y.LastOwnerID = LLUUID.Zero; |
57 | y.GroupPosition = groupPos; | 71 | y.GroupPosition = groupPos; |
58 | y.OffsetPosition = new LLVector3(0, 0, 0); | 72 | y.OffsetPosition = new LLVector3(0, 0, 0); |
59 | y.RotationOffset = new LLQuaternion(0,0,0,0); | 73 | y.RotationOffset = new LLQuaternion(0,0,0,0); |
60 | y.Velocity = new LLVector3(0, 0, 0); | 74 | y.Velocity = new LLVector3(0, 0, 0); |
61 | y.RotationalVelocity = new LLVector3(0, 0, 0); | 75 | y.RotationalVelocity = new LLVector3(0, 0, 0); |
62 | y.AngularVelocity = new LLVector3(0, 0, 0); | 76 | y.AngularVelocity = new LLVector3(0, 0, 0); |
63 | y.Acceleration = new LLVector3(0, 0, 0); | 77 | y.Acceleration = new LLVector3(0, 0, 0); |
64 | 78 | ||
65 | y.Flags = 0; | 79 | y.Flags = 0; |
66 | y.TrimPermissions(); | 80 | y.TrimPermissions(); |
67 | 81 | ||
68 | //Initialize group and add part as root part | 82 | //Initialize group and add part as root part |
69 | x.SetScene(scene); | 83 | x.SetScene(scene); |
70 | y.SetParent(x); | 84 | y.SetParent(x); |
71 | y.ParentID = 0; | 85 | y.ParentID = 0; |
72 | y.LinkNum = 0; | 86 | y.LinkNum = 0; |
73 | x.Children.Add(y.UUID, y); | 87 | x.Children.Add(y.UUID, y); |
74 | x.RootPart = y; | 88 | x.RootPart = y; |
75 | x.RegionHandle = scene.RegionInfo.RegionHandle; | 89 | x.RegionHandle = scene.RegionInfo.RegionHandle; |
76 | x.SetScene(scene); | 90 | x.SetScene(scene); |
77 | 91 | ||
78 | m_Entity = x; | 92 | m_Entity = x; |
79 | } | 93 | } |
80 | } | 94 | |
81 | } | 95 | #endregion Private Methods |
96 | } | ||
97 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs index c3817ef..6f34d3b 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs | |||
@@ -1,87 +1,113 @@ | |||
1 | #region Header | ||
2 | |||
1 | // SceneObjectGroupDiff.cs | 3 | // SceneObjectGroupDiff.cs |
2 | // User: bongiojp | 4 | // User: bongiojp |
3 | 5 | ||
6 | #endregion Header | ||
7 | |||
4 | using System; | 8 | using System; |
5 | using System.Collections.Generic; | 9 | using System.Collections.Generic; |
10 | using System.Diagnostics; | ||
6 | using System.Drawing; | 11 | using System.Drawing; |
12 | |||
7 | using libsecondlife; | 13 | using libsecondlife; |
14 | |||
8 | using Nini.Config; | 15 | using Nini.Config; |
16 | |||
9 | using OpenSim.Framework; | 17 | using OpenSim.Framework; |
10 | using OpenSim.Region.Environment.Interfaces; | 18 | using OpenSim.Region.Environment.Interfaces; |
11 | using OpenSim.Region.Environment.Scenes; | 19 | using OpenSim.Region.Environment.Scenes; |
12 | using log4net; | ||
13 | using OpenSim.Region.Physics.Manager; | 20 | using OpenSim.Region.Physics.Manager; |
21 | |||
22 | using log4net; | ||
23 | |||
14 | using Axiom.Math; | 24 | using Axiom.Math; |
15 | using System.Diagnostics; | ||
16 | 25 | ||
17 | namespace OpenSim.Region.Environment.Modules.ContentManagement | 26 | namespace OpenSim.Region.Environment.Modules.ContentManagement |
18 | { | 27 | { |
19 | [Flags] | 28 | #region Enumerations |
20 | public enum Diff | 29 | |
21 | { | 30 | [Flags] |
22 | NONE = 0, | 31 | public enum Diff |
23 | FACECOLOR = 1, | 32 | { |
24 | SHAPE = 1<<1, | 33 | NONE = 0, |
25 | MATERIAL = 1<<2, | 34 | FACECOLOR = 1, |
26 | TEXTURE = 1<<3, | 35 | SHAPE = 1<<1, |
27 | SCALE = 1<<4, | 36 | MATERIAL = 1<<2, |
28 | POSITION = 1<<5, | 37 | TEXTURE = 1<<3, |
29 | OFFSETPOSITION = 1<<6, | 38 | SCALE = 1<<4, |
30 | ROTATIONOFFSET = 1<<7, | 39 | POSITION = 1<<5, |
31 | ROTATIONALVELOCITY = 1<<8, | 40 | OFFSETPOSITION = 1<<6, |
32 | ACCELERATION = 1<<9, | 41 | ROTATIONOFFSET = 1<<7, |
33 | ANGULARVELOCITY = 1<<10, | 42 | ROTATIONALVELOCITY = 1<<8, |
34 | VELOCITY = 1<<11, | 43 | ACCELERATION = 1<<9, |
35 | OBJECTOWNER = 1<<12, | 44 | ANGULARVELOCITY = 1<<10, |
36 | PERMISSIONS = 1<<13, | 45 | VELOCITY = 1<<11, |
37 | DESCRIPTION = 1<<14, | 46 | OBJECTOWNER = 1<<12, |
38 | NAME = 1<<15, | 47 | PERMISSIONS = 1<<13, |
39 | SCRIPT = 1<<16, | 48 | DESCRIPTION = 1<<14, |
40 | CLICKACTION = 1<<17, | 49 | NAME = 1<<15, |
41 | PARTICLESYSTEM = 1<<18, | 50 | SCRIPT = 1<<16, |
42 | GLOW = 1<<19, | 51 | CLICKACTION = 1<<17, |
43 | SALEPRICE = 1<<20, | 52 | PARTICLESYSTEM = 1<<18, |
44 | SITNAME = 1<<21, | 53 | GLOW = 1<<19, |
45 | SITTARGETORIENTATION = 1<<22, | 54 | SALEPRICE = 1<<20, |
46 | SITTARGETPOSITION = 1<<23, | 55 | SITNAME = 1<<21, |
47 | TEXT = 1<<24, | 56 | SITTARGETORIENTATION = 1<<22, |
48 | TOUCHNAME = 1<<25 | 57 | SITTARGETPOSITION = 1<<23, |
49 | }; | 58 | TEXT = 1<<24, |
50 | 59 | TOUCHNAME = 1<<25 | |
51 | public static class Difference | 60 | } |
52 | { | 61 | |
53 | static float TimeToDiff = 0; | 62 | #endregion Enumerations |
54 | 63 | ||
55 | private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 64 | public static class Difference |
56 | 65 | { | |
57 | private static int TruncateSignificant(float num, int digits) | 66 | #region Static Fields |
58 | { | 67 | |
59 | return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits)); | 68 | static float TimeToDiff = 0; |
60 | // return (int) ((num * (10*digits))/10*digits); | 69 | private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
61 | } | 70 | |
62 | 71 | #endregion Static Fields | |
63 | private static bool AreVectorsEquivalent(LLVector3 first, LLVector3 second) | 72 | |
64 | { | 73 | #region Private Methods |
65 | if(TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2) | 74 | |
66 | && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2) | 75 | private static bool AreQuaternionsEquivalent(LLQuaternion first, LLQuaternion second) |
67 | && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2) | 76 | { |
68 | ) | 77 | LLVector3 firstVector = llRot2Euler(first); |
69 | return true; | 78 | LLVector3 secondVector = llRot2Euler(second); |
70 | else | 79 | return AreVectorsEquivalent(firstVector, secondVector); |
71 | return false; | 80 | } |
72 | } | 81 | |
73 | 82 | private static bool AreVectorsEquivalent(LLVector3 first, LLVector3 second) | |
74 | private static bool AreQuaternionsEquivalent(LLQuaternion first, LLQuaternion second) | 83 | { |
75 | { | 84 | if(TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2) |
76 | LLVector3 firstVector = llRot2Euler(first); | 85 | && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2) |
77 | LLVector3 secondVector = llRot2Euler(second); | 86 | && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2) |
78 | return AreVectorsEquivalent(firstVector, secondVector); | 87 | ) |
79 | } | 88 | return true; |
80 | 89 | else | |
81 | // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 90 | return false; |
82 | // Also changed the original function from LSL_Types to LL types | 91 | } |
92 | |||
93 | // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs | ||
94 | private static double NormalizeAngle(double angle) | ||
95 | { | ||
96 | angle = angle % (Math.PI * 2); | ||
97 | if (angle < 0) angle = angle + Math.PI * 2; | ||
98 | return angle; | ||
99 | } | ||
100 | |||
101 | private static int TruncateSignificant(float num, int digits) | ||
102 | { | ||
103 | return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits)); | ||
104 | // return (int) ((num * (10*digits))/10*digits); | ||
105 | } | ||
106 | |||
107 | // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs | ||
108 | // Also changed the original function from LSL_Types to LL types | ||
83 | private static LLVector3 llRot2Euler(LLQuaternion r) | 109 | private static LLVector3 llRot2Euler(LLQuaternion r) |
84 | { | 110 | { |
85 | LLQuaternion t = new LLQuaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W); | 111 | LLQuaternion t = new LLQuaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W); |
86 | double m = (t.X + t.Y + t.Z + t.W); | 112 | double m = (t.X + t.Y + t.Z + t.W); |
87 | if (m == 0) return new LLVector3(); | 113 | if (m == 0) return new LLVector3(); |
@@ -96,74 +122,72 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement | |||
96 | else | 122 | else |
97 | return new LLVector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z))); | 123 | return new LLVector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z))); |
98 | } | 124 | } |
99 | 125 | ||
100 | // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 126 | #endregion Private Methods |
101 | private static double NormalizeAngle(double angle) | 127 | |
102 | { | 128 | #region Public Methods |
103 | angle = angle % (Math.PI * 2); | 129 | |
104 | if (angle < 0) angle = angle + Math.PI * 2; | 130 | /// <summary> |
105 | return angle; | 131 | /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts |
132 | /// and returns a Diff bitmask which details what the differences are. | ||
133 | /// </summary> | ||
134 | public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second) | ||
135 | { | ||
136 | Stopwatch x = new Stopwatch(); | ||
137 | x.Start(); | ||
138 | |||
139 | Diff result = 0; | ||
140 | |||
141 | // VECTOR COMPARISONS | ||
142 | if(! AreVectorsEquivalent(first.Acceleration, second.Acceleration)) | ||
143 | result |= Diff.ACCELERATION; | ||
144 | if(! AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition)) | ||
145 | result |= Diff.POSITION; | ||
146 | if(! AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity)) | ||
147 | result |= Diff.ANGULARVELOCITY; | ||
148 | if(! AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition)) | ||
149 | result |= Diff.OFFSETPOSITION; | ||
150 | if(! AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity)) | ||
151 | result |= Diff.ROTATIONALVELOCITY; | ||
152 | if(! AreVectorsEquivalent(first.Scale, second.Scale)) | ||
153 | result |= Diff.SCALE; | ||
154 | if(! AreVectorsEquivalent(first.Velocity, second.Velocity)) | ||
155 | result |= Diff.VELOCITY; | ||
156 | |||
157 | |||
158 | // QUATERNION COMPARISONS | ||
159 | if(! AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset)) | ||
160 | result |= Diff.ROTATIONOFFSET; | ||
161 | |||
162 | |||
163 | // MISC COMPARISONS (LLUUID, Byte) | ||
164 | if(first.ClickAction != second.ClickAction) | ||
165 | result |= Diff.CLICKACTION; | ||
166 | if(first.ObjectOwner != second.ObjectOwner) | ||
167 | result |= Diff.OBJECTOWNER; | ||
168 | |||
169 | |||
170 | // STRING COMPARISONS | ||
171 | if(first.Description != second.Description) | ||
172 | result |= Diff.DESCRIPTION; | ||
173 | if(first.Material != second.Material) | ||
174 | result |= Diff.MATERIAL; | ||
175 | if(first.Name != second.Name) | ||
176 | result |= Diff.NAME; | ||
177 | if(first.SitName != second.SitName) | ||
178 | result |= Diff.SITNAME; | ||
179 | if(first.Text != second.Text) | ||
180 | result |= Diff.TEXT; | ||
181 | if(first.TouchName != second.TouchName) | ||
182 | result |= Diff.TOUCHNAME; | ||
183 | |||
184 | x.Stop(); | ||
185 | TimeToDiff += x.ElapsedMilliseconds; | ||
186 | //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff); | ||
187 | |||
188 | return result; | ||
106 | } | 189 | } |
107 | 190 | ||
108 | /// <summary> | 191 | #endregion Public Methods |
109 | /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts | 192 | } |
110 | /// and returns a Diff bitmask which details what the differences are. | 193 | } \ No newline at end of file |
111 | /// </summary> | ||
112 | public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second) | ||
113 | { | ||
114 | Stopwatch x = new Stopwatch(); | ||
115 | x.Start(); | ||
116 | |||
117 | Diff result = 0; | ||
118 | |||
119 | // VECTOR COMPARISONS | ||
120 | if(! AreVectorsEquivalent(first.Acceleration, second.Acceleration)) | ||
121 | result |= Diff.ACCELERATION; | ||
122 | if(! AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition)) | ||
123 | result |= Diff.POSITION; | ||
124 | if(! AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity)) | ||
125 | result |= Diff.ANGULARVELOCITY; | ||
126 | if(! AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition)) | ||
127 | result |= Diff.OFFSETPOSITION; | ||
128 | if(! AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity)) | ||
129 | result |= Diff.ROTATIONALVELOCITY; | ||
130 | if(! AreVectorsEquivalent(first.Scale, second.Scale)) | ||
131 | result |= Diff.SCALE; | ||
132 | if(! AreVectorsEquivalent(first.Velocity, second.Velocity)) | ||
133 | result |= Diff.VELOCITY; | ||
134 | |||
135 | |||
136 | // QUATERNION COMPARISONS | ||
137 | if(! AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset)) | ||
138 | result |= Diff.ROTATIONOFFSET; | ||
139 | |||
140 | |||
141 | // MISC COMPARISONS (LLUUID, Byte) | ||
142 | if(first.ClickAction != second.ClickAction) | ||
143 | result |= Diff.CLICKACTION; | ||
144 | if(first.ObjectOwner != second.ObjectOwner) | ||
145 | result |= Diff.OBJECTOWNER; | ||
146 | |||
147 | |||
148 | // STRING COMPARISONS | ||
149 | if(first.Description != second.Description) | ||
150 | result |= Diff.DESCRIPTION; | ||
151 | if(first.Material != second.Material) | ||
152 | result |= Diff.MATERIAL; | ||
153 | if(first.Name != second.Name) | ||
154 | result |= Diff.NAME; | ||
155 | if(first.SitName != second.SitName) | ||
156 | result |= Diff.SITNAME; | ||
157 | if(first.Text != second.Text) | ||
158 | result |= Diff.TEXT; | ||
159 | if(first.TouchName != second.TouchName) | ||
160 | result |= Diff.TOUCHNAME; | ||
161 | |||
162 | x.Stop(); | ||
163 | TimeToDiff += x.ElapsedMilliseconds; | ||
164 | //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff); | ||
165 | |||
166 | return result; | ||
167 | } | ||
168 | } | ||
169 | } | ||