diff options
Partial Linking of prim groups should work (its partial as currently only the root prim of the child group will actually get linked, working on linking the rest now).
Multiple prim groups are now stored in the sqlite database and are reloaded correctly.
4 files changed, 201 insertions, 60 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index e7f5f56..42d8c27 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -459,7 +459,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
459 | { | 459 | { |
460 | AddEntityFromStorage(prim); | 460 | AddEntityFromStorage(prim); |
461 | } | 461 | } |
462 | MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " object(s)"); | 462 | MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); |
463 | } | 463 | } |
464 | 464 | ||
465 | /// <summary> | 465 | /// <summary> |
@@ -520,6 +520,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
520 | { | 520 | { |
521 | part.LocalID = this.PrimIDAllocate(); | 521 | part.LocalID = this.PrimIDAllocate(); |
522 | } | 522 | } |
523 | sceneObject.UpdateParentIDs(); | ||
523 | this.AddEntity(sceneObject); | 524 | this.AddEntity(sceneObject); |
524 | } | 525 | } |
525 | 526 | ||
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 39b7fb0..dae4b5f 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | |||
@@ -1,5 +1,9 @@ | |||
1 | using System.Collections.Generic; | 1 | using System.Collections.Generic; |
2 | using System.Text; | 2 | using System.Text; |
3 | using System.Xml; | ||
4 | using System.Xml.Serialization; | ||
5 | using System.IO; | ||
6 | using System; | ||
3 | using Axiom.Math; | 7 | using Axiom.Math; |
4 | using libsecondlife; | 8 | using libsecondlife; |
5 | using libsecondlife.Packets; | 9 | using libsecondlife.Packets; |
@@ -22,6 +26,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
22 | 26 | ||
23 | public event PrimCountTaintedDelegate OnPrimCountTainted; | 27 | public event PrimCountTaintedDelegate OnPrimCountTainted; |
24 | 28 | ||
29 | #region Properties | ||
25 | /// <summary> | 30 | /// <summary> |
26 | /// | 31 | /// |
27 | /// </summary> | 32 | /// </summary> |
@@ -111,6 +116,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
111 | set { m_isSelected = value; } | 116 | set { m_isSelected = value; } |
112 | } | 117 | } |
113 | 118 | ||
119 | #endregion | ||
120 | |||
121 | #region Constructors | ||
114 | /// <summary> | 122 | /// <summary> |
115 | /// | 123 | /// |
116 | /// </summary> | 124 | /// </summary> |
@@ -122,6 +130,31 @@ namespace OpenSim.Region.Environment.Scenes | |||
122 | /// <summary> | 130 | /// <summary> |
123 | /// | 131 | /// |
124 | /// </summary> | 132 | /// </summary> |
133 | public SceneObjectGroup(Scene scene, ulong regionHandle, string xmlData) | ||
134 | { | ||
135 | m_scene = scene; | ||
136 | m_regionHandle = regionHandle; | ||
137 | |||
138 | StringReader sr = new StringReader(xmlData); | ||
139 | XmlTextReader reader = new XmlTextReader(sr); | ||
140 | reader.ReadStartElement("SceneObjectGroup"); | ||
141 | reader.ReadStartElement("RootPart"); | ||
142 | this.m_rootPart = SceneObjectPart.FromXml(reader); | ||
143 | reader.ReadEndElement(); | ||
144 | //TODO: read and create rest of the parts | ||
145 | reader.ReadEndElement(); | ||
146 | reader.Close(); | ||
147 | sr.Close(); | ||
148 | |||
149 | this.m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
150 | this.m_rootPart.LocalID = m_scene.PrimIDAllocate(); | ||
151 | this.m_rootPart.RegionHandle = m_regionHandle; | ||
152 | m_scene.EventManager.OnBackup += this.ProcessBackup; | ||
153 | } | ||
154 | |||
155 | /// <summary> | ||
156 | /// | ||
157 | /// </summary> | ||
125 | public SceneObjectGroup(byte[] data) | 158 | public SceneObjectGroup(byte[] data) |
126 | { | 159 | { |
127 | 160 | ||
@@ -142,7 +175,25 @@ namespace OpenSim.Region.Environment.Scenes | |||
142 | this.SetPartAsRoot(newPart); | 175 | this.SetPartAsRoot(newPart); |
143 | m_scene.EventManager.OnBackup += this.ProcessBackup; | 176 | m_scene.EventManager.OnBackup += this.ProcessBackup; |
144 | } | 177 | } |
178 | #endregion | ||
145 | 179 | ||
180 | public string ToXmlString() | ||
181 | { | ||
182 | StringWriter sw = new StringWriter(); | ||
183 | //StreamWriter st = new StreamWriter("testxml.txt"); | ||
184 | XmlTextWriter writer = new XmlTextWriter(sw); | ||
185 | writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); | ||
186 | writer.WriteStartElement(String.Empty, "RootPart", String.Empty); | ||
187 | m_rootPart.ToXml(writer); | ||
188 | writer.WriteEndElement(); | ||
189 | writer.WriteEndElement(); | ||
190 | writer.Close(); | ||
191 | // System.Console.WriteLine("prim: " + sw.ToString()); | ||
192 | return sw.ToString(); | ||
193 | // st.Close(); | ||
194 | // return ""; | ||
195 | |||
196 | } | ||
146 | 197 | ||
147 | #region Copying | 198 | #region Copying |
148 | /// <summary> | 199 | /// <summary> |
@@ -170,23 +221,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
170 | } | 221 | } |
171 | 222 | ||
172 | /// <summary> | 223 | /// <summary> |
173 | /// Added as a way for the storage provider to reset the scene, | ||
174 | /// most likely a better way to do this sort of thing but for now... | ||
175 | /// </summary> | ||
176 | /// <param name="scene"></param> | ||
177 | public void SetScene(Scene scene) | ||
178 | { | ||
179 | m_scene = scene; | ||
180 | m_scene.EventManager.OnBackup += this.ProcessBackup; | ||
181 | } | ||
182 | |||
183 | public void AddPart(SceneObjectPart part) | ||
184 | { | ||
185 | part.SetParent(this); | ||
186 | this.m_parts.Add(part.UUID, part); | ||
187 | } | ||
188 | |||
189 | /// <summary> | ||
190 | /// | 224 | /// |
191 | /// </summary> | 225 | /// </summary> |
192 | /// <param name="part"></param> | 226 | /// <param name="part"></param> |
@@ -209,6 +243,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
209 | } | 243 | } |
210 | #endregion | 244 | #endregion |
211 | 245 | ||
246 | #region Scheduling | ||
212 | /// <summary> | 247 | /// <summary> |
213 | /// | 248 | /// |
214 | /// </summary> | 249 | /// </summary> |
@@ -264,15 +299,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
264 | } | 299 | } |
265 | } | 300 | } |
266 | 301 | ||
267 | /// <summary> | 302 | #endregion |
268 | /// | ||
269 | /// </summary> | ||
270 | /// <param name="objectGroup"></param> | ||
271 | public void LinkToGroup(SceneObjectGroup objectGroup) | ||
272 | { | ||
273 | |||
274 | } | ||
275 | 303 | ||
304 | #region SceneGroupPart Methods | ||
276 | /// <summary> | 305 | /// <summary> |
277 | /// | 306 | /// |
278 | /// </summary> | 307 | /// </summary> |
@@ -339,26 +368,37 @@ namespace OpenSim.Region.Environment.Scenes | |||
339 | } | 368 | } |
340 | return false; | 369 | return false; |
341 | } | 370 | } |
371 | #endregion | ||
342 | 372 | ||
373 | #region Packet Handlers | ||
343 | /// <summary> | 374 | /// <summary> |
344 | /// | 375 | /// |
345 | /// </summary> | 376 | /// </summary> |
346 | public void TriggerTainted() | 377 | /// <param name="objectGroup"></param> |
347 | { | 378 | public void LinkToGroup(SceneObjectGroup objectGroup) |
348 | if (OnPrimCountTainted != null) | ||
349 | { | ||
350 | this.OnPrimCountTainted(); | ||
351 | } | ||
352 | } | ||
353 | |||
354 | /// <summary> | ||
355 | /// Processes backup | ||
356 | /// </summary> | ||
357 | /// <param name="datastore"></param> | ||
358 | public void ProcessBackup(OpenSim.Region.Interfaces.IRegionDataStore datastore) | ||
359 | { | 379 | { |
360 | datastore.StoreObject(this); | 380 | SceneObjectPart linkPart = objectGroup.m_rootPart; |
381 | linkPart.OffsetPosition = linkPart.GroupPosition - this.Pos; | ||
382 | linkPart.GroupPosition = this.Pos; | ||
383 | |||
384 | Vector3 axPos = new Vector3(linkPart.OffsetPosition.X, linkPart.OffsetPosition.Y, linkPart.OffsetPosition.Z); | ||
385 | Quaternion parentRot = new Quaternion(this.m_rootPart.RotationOffset.W, this.m_rootPart.RotationOffset.X, this.m_rootPart.RotationOffset.Y, this.m_rootPart.RotationOffset.Z); | ||
386 | axPos = parentRot.Inverse() * axPos; | ||
387 | linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); | ||
388 | Quaternion oldRot = new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y, linkPart.RotationOffset.Z); | ||
389 | Quaternion newRot = parentRot * oldRot; | ||
390 | linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); | ||
391 | linkPart.ParentID = this.m_rootPart.LocalID; | ||
392 | this.m_parts.Add(linkPart.UUID, linkPart); | ||
393 | linkPart.SetParent(this); | ||
394 | |||
395 | //TODO: rest of parts | ||
396 | |||
397 | m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup; | ||
398 | m_scene.DeleteEntity(objectGroup.UUID); | ||
399 | this.ScheduleGroupForFullUpdate(); | ||
361 | } | 400 | } |
401 | |||
362 | /// <summary> | 402 | /// <summary> |
363 | /// | 403 | /// |
364 | /// </summary> | 404 | /// </summary> |
@@ -469,6 +509,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
469 | part.UpdateTextureEntry(textureEntry); | 509 | part.UpdateTextureEntry(textureEntry); |
470 | } | 510 | } |
471 | } | 511 | } |
512 | #endregion | ||
472 | 513 | ||
473 | #region Shape | 514 | #region Shape |
474 | /// <summary> | 515 | /// <summary> |
@@ -485,6 +526,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
485 | } | 526 | } |
486 | #endregion | 527 | #endregion |
487 | 528 | ||
529 | #region Resize | ||
488 | /// <summary> | 530 | /// <summary> |
489 | /// | 531 | /// |
490 | /// </summary> | 532 | /// </summary> |
@@ -498,6 +540,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
498 | part.Resize(scale); | 540 | part.Resize(scale); |
499 | } | 541 | } |
500 | } | 542 | } |
543 | #endregion | ||
501 | 544 | ||
502 | #region Position | 545 | #region Position |
503 | /// <summary> | 546 | /// <summary> |
@@ -636,8 +679,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
636 | private void SetPartAsRoot(SceneObjectPart part) | 679 | private void SetPartAsRoot(SceneObjectPart part) |
637 | { | 680 | { |
638 | this.m_rootPart = part; | 681 | this.m_rootPart = part; |
639 | //this.m_uuid= part.UUID; | ||
640 | // this.m_localId = part.LocalID; | ||
641 | } | 682 | } |
642 | 683 | ||
643 | /// <summary> | 684 | /// <summary> |
@@ -658,6 +699,29 @@ namespace OpenSim.Region.Environment.Scenes | |||
658 | return m_scene.RequestAvatarList(); | 699 | return m_scene.RequestAvatarList(); |
659 | } | 700 | } |
660 | 701 | ||
702 | #region Events | ||
703 | /// <summary> | ||
704 | /// | ||
705 | /// </summary> | ||
706 | public void TriggerTainted() | ||
707 | { | ||
708 | if (OnPrimCountTainted != null) | ||
709 | { | ||
710 | this.OnPrimCountTainted(); | ||
711 | } | ||
712 | } | ||
713 | |||
714 | /// <summary> | ||
715 | /// Processes backup | ||
716 | /// </summary> | ||
717 | /// <param name="datastore"></param> | ||
718 | public void ProcessBackup(OpenSim.Region.Interfaces.IRegionDataStore datastore) | ||
719 | { | ||
720 | datastore.StoreObject(this); | ||
721 | } | ||
722 | #endregion | ||
723 | |||
724 | #region Client Updating | ||
661 | public void SendFullUpdateToClient(IClientAPI remoteClient) | 725 | public void SendFullUpdateToClient(IClientAPI remoteClient) |
662 | { | 726 | { |
663 | lock (this.m_parts) | 727 | lock (this.m_parts) |
@@ -702,5 +766,41 @@ namespace OpenSim.Region.Environment.Scenes | |||
702 | part.SendTerseUpdateToClient(remoteClient); | 766 | part.SendTerseUpdateToClient(remoteClient); |
703 | } | 767 | } |
704 | } | 768 | } |
769 | #endregion | ||
770 | |||
771 | /// <summary> | ||
772 | /// Added as a way for the storage provider to reset the scene, | ||
773 | /// most likely a better way to do this sort of thing but for now... | ||
774 | /// </summary> | ||
775 | /// <param name="scene"></param> | ||
776 | public void SetScene(Scene scene) | ||
777 | { | ||
778 | m_scene = scene; | ||
779 | m_scene.EventManager.OnBackup += this.ProcessBackup; | ||
780 | } | ||
781 | |||
782 | /// <summary> | ||
783 | /// | ||
784 | /// </summary> | ||
785 | /// <param name="part"></param> | ||
786 | public void AddPart(SceneObjectPart part) | ||
787 | { | ||
788 | part.SetParent(this); | ||
789 | this.m_parts.Add(part.UUID, part); | ||
790 | } | ||
791 | |||
792 | /// <summary> | ||
793 | /// | ||
794 | /// </summary> | ||
795 | public void UpdateParentIDs() | ||
796 | { | ||
797 | foreach (SceneObjectPart part in this.m_parts.Values) | ||
798 | { | ||
799 | if (part.UUID != this.m_rootPart.UUID) | ||
800 | { | ||
801 | part.ParentID = this.m_rootPart.LocalID; | ||
802 | } | ||
803 | } | ||
804 | } | ||
705 | } | 805 | } |
706 | } | 806 | } |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 1b373aa..c1348c7 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | |||
@@ -1,5 +1,8 @@ | |||
1 | using System.Collections.Generic; | 1 | using System.Collections.Generic; |
2 | using System.Text; | 2 | using System.Text; |
3 | using System.Xml; | ||
4 | using System.Xml.Serialization; | ||
5 | using System.IO; | ||
3 | using System; | 6 | using System; |
4 | using Axiom.Math; | 7 | using Axiom.Math; |
5 | using libsecondlife; | 8 | using libsecondlife; |
@@ -252,6 +255,27 @@ namespace OpenSim.Region.Environment.Scenes | |||
252 | /// <summary> | 255 | /// <summary> |
253 | /// | 256 | /// |
254 | /// </summary> | 257 | /// </summary> |
258 | /// <param name="xmlreader"></param> | ||
259 | /// <returns></returns> | ||
260 | public static SceneObjectPart FromXml(XmlReader xmlReader) | ||
261 | { | ||
262 | XmlSerializer serializer = new XmlSerializer(typeof(SceneObjectPart)); | ||
263 | return (SceneObjectPart)serializer.Deserialize(xmlReader); | ||
264 | } | ||
265 | |||
266 | /// <summary> | ||
267 | /// | ||
268 | /// </summary> | ||
269 | /// <param name="xmlWriter"></param> | ||
270 | public void ToXml(XmlWriter xmlWriter) | ||
271 | { | ||
272 | XmlSerializer serializer = new XmlSerializer(typeof(SceneObjectPart)); | ||
273 | serializer.Serialize(xmlWriter, this); | ||
274 | } | ||
275 | |||
276 | /// <summary> | ||
277 | /// | ||
278 | /// </summary> | ||
255 | public void SetParent(SceneObjectGroup parent) | 279 | public void SetParent(SceneObjectGroup parent) |
256 | { | 280 | { |
257 | m_parentGroup = parent; | 281 | m_parentGroup = parent; |
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs index 5d1592c..bd6658c 100644 --- a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs +++ b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs | |||
@@ -308,7 +308,6 @@ namespace OpenSim.DataStore.MonoSqliteStorage | |||
308 | 308 | ||
309 | private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID) | 309 | private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID) |
310 | { | 310 | { |
311 | Console.WriteLine("scene Group for this prim is " + sceneGroupID); | ||
312 | row["UUID"] = prim.UUID; | 311 | row["UUID"] = prim.UUID; |
313 | row["ParentID"] = prim.ParentID; | 312 | row["ParentID"] = prim.ParentID; |
314 | row["CreationDate"] = prim.CreationDate; | 313 | row["CreationDate"] = prim.CreationDate; |
@@ -481,37 +480,54 @@ namespace OpenSim.DataStore.MonoSqliteStorage | |||
481 | 480 | ||
482 | public List<SceneObjectGroup> LoadObjects() | 481 | public List<SceneObjectGroup> LoadObjects() |
483 | { | 482 | { |
483 | Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>(); | ||
484 | List<SceneObjectGroup> retvals = new List<SceneObjectGroup>(); | 484 | List<SceneObjectGroup> retvals = new List<SceneObjectGroup>(); |
485 | 485 | ||
486 | DataTable prims = ds.Tables["prims"]; | 486 | DataTable prims = ds.Tables["prims"]; |
487 | DataTable shapes = ds.Tables["primshapes"]; | 487 | DataTable shapes = ds.Tables["primshapes"]; |
488 | 488 | ||
489 | // This only supports 1 prim per SceneObjectGroup. Need to fix later | ||
490 | foreach (DataRow primRow in prims.Rows) | 489 | foreach (DataRow primRow in prims.Rows) |
491 | { | 490 | { |
492 | SceneObjectGroup group = new SceneObjectGroup(); | 491 | string uuid = (string)primRow["UUID"]; |
493 | SceneObjectPart prim = buildPrim(primRow); | 492 | string objID = (string)primRow["SceneGroupID"]; |
494 | DataRow shapeRow = shapes.Rows.Find(prim.UUID); | 493 | if (uuid == objID) //is new SceneObjectGroup ? |
495 | if (shapeRow != null) | ||
496 | { | 494 | { |
497 | prim.Shape = buildShape(shapeRow); | 495 | SceneObjectGroup group = new SceneObjectGroup(); |
496 | SceneObjectPart prim = buildPrim(primRow); | ||
497 | DataRow shapeRow = shapes.Rows.Find(prim.UUID); | ||
498 | if (shapeRow != null) | ||
499 | { | ||
500 | prim.Shape = buildShape(shapeRow); | ||
501 | } | ||
502 | else | ||
503 | { | ||
504 | Console.WriteLine("No shape found for prim in storage, so setting default box shape"); | ||
505 | prim.Shape = BoxShape.Default; | ||
506 | } | ||
507 | group.AddPart(prim); | ||
508 | group.RootPart = prim; | ||
509 | |||
510 | createdObjects.Add(group.UUID, group); | ||
511 | retvals.Add(group); | ||
498 | } | 512 | } |
499 | else | 513 | else |
500 | { | 514 | { |
501 | Console.WriteLine("No shape found for prim in storage, so setting default box shape"); | 515 | SceneObjectPart prim = buildPrim(primRow); |
502 | prim.Shape = BoxShape.Default; | 516 | DataRow shapeRow = shapes.Rows.Find(prim.UUID); |
517 | if (shapeRow != null) | ||
518 | { | ||
519 | prim.Shape = buildShape(shapeRow); | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | Console.WriteLine("No shape found for prim in storage, so setting default box shape"); | ||
524 | prim.Shape = BoxShape.Default; | ||
525 | } | ||
526 | createdObjects[new LLUUID(objID)].AddPart(prim); | ||
503 | } | 527 | } |
504 | group.AddPart(prim); | ||
505 | // TODO: there are a couple of known issues to get this to work | ||
506 | // * While we can add Children, we can't set the root part (or | ||
507 | // or even figure out which should be the root part) | ||
508 | // * region handle may need to be persisted, it isn't now | ||
509 | group.RootPart = prim; | ||
510 | |||
511 | retvals.Add(group); | ||
512 | } | 528 | } |
513 | 529 | ||
514 | MainLog.Instance.Verbose("DATASTORE", "Sqlite - LoadObjects found " + prims.Rows.Count + " objects"); | 530 | MainLog.Instance.Verbose("DATASTORE", "Sqlite - LoadObjects found " + prims.Rows.Count + " primitives"); |
515 | 531 | ||
516 | return retvals; | 532 | return retvals; |
517 | } | 533 | } |