diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 182 |
1 files changed, 147 insertions, 35 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 4676a30..f35a7c5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -369,14 +369,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
369 | } | 369 | } |
370 | 370 | ||
371 | lockPartsForRead(true); | 371 | lockPartsForRead(true); |
372 | |||
373 | if (RootPart.GetStatusSandbox()) | ||
372 | { | 374 | { |
373 | foreach (SceneObjectPart part in m_parts.Values) | 375 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
374 | { | 376 | { |
375 | 377 | RootPart.ScriptSetPhysicsStatus(false); | |
376 | part.GroupPosition = val; | 378 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), |
377 | 379 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); | |
380 | return; | ||
378 | } | 381 | } |
379 | } | 382 | } |
383 | |||
384 | foreach (SceneObjectPart part in m_parts.Values) | ||
385 | { | ||
386 | part.GroupPosition = val; | ||
387 | } | ||
388 | |||
380 | lockPartsForRead(false); | 389 | lockPartsForRead(false); |
381 | 390 | ||
382 | //if (m_rootPart.PhysActor != null) | 391 | //if (m_rootPart.PhysActor != null) |
@@ -470,6 +479,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
470 | } | 479 | } |
471 | } | 480 | } |
472 | 481 | ||
482 | private SceneObjectPart m_PlaySoundMasterPrim = null; | ||
483 | public SceneObjectPart PlaySoundMasterPrim | ||
484 | { | ||
485 | get { return m_PlaySoundMasterPrim; } | ||
486 | set { m_PlaySoundMasterPrim = value; } | ||
487 | } | ||
488 | |||
489 | private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>(); | ||
490 | public List<SceneObjectPart> PlaySoundSlavePrims | ||
491 | { | ||
492 | get { return m_LoopSoundSlavePrims; } | ||
493 | set { m_LoopSoundSlavePrims = value; } | ||
494 | } | ||
495 | |||
496 | private SceneObjectPart m_LoopSoundMasterPrim = null; | ||
497 | public SceneObjectPart LoopSoundMasterPrim | ||
498 | { | ||
499 | get { return m_LoopSoundMasterPrim; } | ||
500 | set { m_LoopSoundMasterPrim = value; } | ||
501 | } | ||
502 | |||
503 | private List<SceneObjectPart> m_LoopSoundSlavePrims = new List<SceneObjectPart>(); | ||
504 | public List<SceneObjectPart> LoopSoundSlavePrims | ||
505 | { | ||
506 | get { return m_LoopSoundSlavePrims; } | ||
507 | set { m_LoopSoundSlavePrims = value; } | ||
508 | } | ||
509 | |||
473 | // The UUID for the Region this Object is in. | 510 | // The UUID for the Region this Object is in. |
474 | public UUID RegionUUID | 511 | public UUID RegionUUID |
475 | { | 512 | { |
@@ -584,7 +621,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
584 | 621 | ||
585 | if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0) | 622 | if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0) |
586 | m_rootPart.ParentID = 0; | 623 | m_rootPart.ParentID = 0; |
587 | if (m_rootPart.LocalId==0) | 624 | if (m_rootPart.LocalId == 0) |
588 | m_rootPart.LocalId = m_scene.AllocateLocalId(); | 625 | m_rootPart.LocalId = m_scene.AllocateLocalId(); |
589 | 626 | ||
590 | // No need to lock here since the object isn't yet in a scene | 627 | // No need to lock here since the object isn't yet in a scene |
@@ -1586,6 +1623,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1586 | /// <param name="part"></param> | 1623 | /// <param name="part"></param> |
1587 | internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) | 1624 | internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) |
1588 | { | 1625 | { |
1626 | // m_log.DebugFormat( | ||
1627 | // "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); | ||
1628 | |||
1589 | if (m_rootPart.UUID == part.UUID) | 1629 | if (m_rootPart.UUID == part.UUID) |
1590 | { | 1630 | { |
1591 | if (IsAttachment) | 1631 | if (IsAttachment) |
@@ -2084,7 +2124,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2084 | 2124 | ||
2085 | foreach (SceneObjectPart part in m_parts.Values) | 2125 | foreach (SceneObjectPart part in m_parts.Values) |
2086 | { | 2126 | { |
2087 | 2127 | if (!IsSelected) | |
2128 | part.UpdateLookAt(); | ||
2129 | |||
2088 | part.SendScheduledUpdates(); | 2130 | part.SendScheduledUpdates(); |
2089 | 2131 | ||
2090 | } | 2132 | } |
@@ -2434,7 +2476,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2434 | 2476 | ||
2435 | AttachToBackup(); | 2477 | AttachToBackup(); |
2436 | 2478 | ||
2437 | |||
2438 | // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the | 2479 | // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the |
2439 | // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and | 2480 | // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and |
2440 | // unmoved prims! | 2481 | // unmoved prims! |
@@ -2449,9 +2490,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2449 | /// an independent SceneObjectGroup. | 2490 | /// an independent SceneObjectGroup. |
2450 | /// </summary> | 2491 | /// </summary> |
2451 | /// <param name="partID"></param> | 2492 | /// <param name="partID"></param> |
2452 | public void DelinkFromGroup(uint partID) | 2493 | /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> |
2494 | public SceneObjectGroup DelinkFromGroup(uint partID) | ||
2453 | { | 2495 | { |
2454 | DelinkFromGroup(partID, true); | 2496 | return DelinkFromGroup(partID, true); |
2455 | } | 2497 | } |
2456 | 2498 | ||
2457 | /// <summary> | 2499 | /// <summary> |
@@ -2460,28 +2502,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
2460 | /// </summary> | 2502 | /// </summary> |
2461 | /// <param name="partID"></param> | 2503 | /// <param name="partID"></param> |
2462 | /// <param name="sendEvents"></param> | 2504 | /// <param name="sendEvents"></param> |
2463 | public void DelinkFromGroup(uint partID, bool sendEvents) | 2505 | /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> |
2506 | public SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents) | ||
2464 | { | 2507 | { |
2465 | SceneObjectPart linkPart = GetChildPart(partID); | 2508 | SceneObjectPart linkPart = GetChildPart(partID); |
2466 | 2509 | ||
2467 | if (linkPart != null) | 2510 | if (linkPart != null) |
2468 | { | 2511 | { |
2469 | DelinkFromGroup(linkPart, sendEvents); | 2512 | return DelinkFromGroup(linkPart, sendEvents); |
2470 | } | 2513 | } |
2471 | else | 2514 | else |
2472 | { | 2515 | { |
2473 | m_log.InfoFormat("[SCENE OBJECT GROUP]: " + | 2516 | m_log.WarnFormat("[SCENE OBJECT GROUP]: " + |
2474 | "DelinkFromGroup(): Child prim {0} not found in object {1}, {2}", | 2517 | "DelinkFromGroup(): Child prim {0} not found in object {1}, {2}", |
2475 | partID, LocalId, UUID); | 2518 | partID, LocalId, UUID); |
2519 | |||
2520 | return null; | ||
2476 | } | 2521 | } |
2477 | } | 2522 | } |
2478 | 2523 | ||
2479 | public void DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents) | 2524 | /// <summary> |
2525 | /// Delink the given prim from this group. The delinked prim is established as | ||
2526 | /// an independent SceneObjectGroup. | ||
2527 | /// </summary> | ||
2528 | /// <param name="partID"></param> | ||
2529 | /// <param name="sendEvents"></param> | ||
2530 | /// <returns>The object group of the newly delinked prim.</returns> | ||
2531 | public SceneObjectGroup DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents) | ||
2480 | { | 2532 | { |
2481 | linkPart.ClearUndoState(); | ||
2482 | // m_log.DebugFormat( | 2533 | // m_log.DebugFormat( |
2483 | // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", | 2534 | // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", |
2484 | // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); | 2535 | // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); |
2536 | |||
2537 | linkPart.ClearUndoState(); | ||
2485 | 2538 | ||
2486 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2539 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2487 | 2540 | ||
@@ -2536,6 +2589,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2536 | 2589 | ||
2537 | //HasGroupChanged = true; | 2590 | //HasGroupChanged = true; |
2538 | //ScheduleGroupForFullUpdate(); | 2591 | //ScheduleGroupForFullUpdate(); |
2592 | |||
2593 | return objectGroup; | ||
2539 | } | 2594 | } |
2540 | 2595 | ||
2541 | /// <summary> | 2596 | /// <summary> |
@@ -2574,7 +2629,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2574 | 2629 | ||
2575 | part.LinkNum = linkNum; | 2630 | part.LinkNum = linkNum; |
2576 | 2631 | ||
2577 | |||
2578 | part.OffsetPosition = part.GroupPosition - AbsolutePosition; | 2632 | part.OffsetPosition = part.GroupPosition - AbsolutePosition; |
2579 | 2633 | ||
2580 | Quaternion rootRotation = m_rootPart.RotationOffset; | 2634 | Quaternion rootRotation = m_rootPart.RotationOffset; |
@@ -2604,11 +2658,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2604 | { | 2658 | { |
2605 | if (m_rootPart.PhysActor.IsPhysical) | 2659 | if (m_rootPart.PhysActor.IsPhysical) |
2606 | { | 2660 | { |
2607 | Vector3 llmoveforce = pos - AbsolutePosition; | 2661 | if (!m_rootPart.BlockGrab) |
2608 | Vector3 grabforce = llmoveforce; | 2662 | { |
2609 | grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass; | 2663 | Vector3 llmoveforce = pos - AbsolutePosition; |
2610 | m_rootPart.PhysActor.AddForce(grabforce,true); | 2664 | Vector3 grabforce = llmoveforce; |
2611 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 2665 | grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass; |
2666 | m_rootPart.PhysActor.AddForce(grabforce, true); | ||
2667 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | ||
2668 | } | ||
2612 | } | 2669 | } |
2613 | else | 2670 | else |
2614 | { | 2671 | { |
@@ -2966,6 +3023,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2966 | SceneObjectPart part = GetChildPart(localID); | 3023 | SceneObjectPart part = GetChildPart(localID); |
2967 | if (part != null) | 3024 | if (part != null) |
2968 | { | 3025 | { |
3026 | part.IgnoreUndoUpdate = true; | ||
2969 | if (scale.X > m_scene.m_maxNonphys) | 3027 | if (scale.X > m_scene.m_maxNonphys) |
2970 | scale.X = m_scene.m_maxNonphys; | 3028 | scale.X = m_scene.m_maxNonphys; |
2971 | if (scale.Y > m_scene.m_maxNonphys) | 3029 | if (scale.Y > m_scene.m_maxNonphys) |
@@ -2992,6 +3050,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2992 | { | 3050 | { |
2993 | if (obPart.UUID != m_rootPart.UUID) | 3051 | if (obPart.UUID != m_rootPart.UUID) |
2994 | { | 3052 | { |
3053 | obPart.IgnoreUndoUpdate = true; | ||
2995 | Vector3 oldSize = new Vector3(obPart.Scale); | 3054 | Vector3 oldSize = new Vector3(obPart.Scale); |
2996 | 3055 | ||
2997 | float f = 1.0f; | 3056 | float f = 1.0f; |
@@ -3050,6 +3109,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3050 | y *= a; | 3109 | y *= a; |
3051 | z *= a; | 3110 | z *= a; |
3052 | } | 3111 | } |
3112 | obPart.IgnoreUndoUpdate = false; | ||
3113 | obPart.StoreUndoState(); | ||
3053 | } | 3114 | } |
3054 | } | 3115 | } |
3055 | } | 3116 | } |
@@ -3066,6 +3127,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3066 | { | 3127 | { |
3067 | foreach (SceneObjectPart obPart in m_parts.Values) | 3128 | foreach (SceneObjectPart obPart in m_parts.Values) |
3068 | { | 3129 | { |
3130 | obPart.IgnoreUndoUpdate = true; | ||
3069 | if (obPart.UUID != m_rootPart.UUID) | 3131 | if (obPart.UUID != m_rootPart.UUID) |
3070 | { | 3132 | { |
3071 | Vector3 currentpos = new Vector3(obPart.OffsetPosition); | 3133 | Vector3 currentpos = new Vector3(obPart.OffsetPosition); |
@@ -3079,6 +3141,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3079 | obPart.Resize(newSize); | 3141 | obPart.Resize(newSize); |
3080 | obPart.UpdateOffSet(currentpos); | 3142 | obPart.UpdateOffSet(currentpos); |
3081 | } | 3143 | } |
3144 | obPart.IgnoreUndoUpdate = false; | ||
3145 | obPart.StoreUndoState(); | ||
3082 | } | 3146 | } |
3083 | } | 3147 | } |
3084 | lockPartsForRead(false); | 3148 | lockPartsForRead(false); |
@@ -3089,6 +3153,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3089 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 3153 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); |
3090 | } | 3154 | } |
3091 | 3155 | ||
3156 | part.IgnoreUndoUpdate = false; | ||
3157 | part.StoreUndoState(); | ||
3092 | HasGroupChanged = true; | 3158 | HasGroupChanged = true; |
3093 | ScheduleGroupForTerseUpdate(); | 3159 | ScheduleGroupForTerseUpdate(); |
3094 | } | 3160 | } |
@@ -3104,13 +3170,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
3104 | /// <param name="pos"></param> | 3170 | /// <param name="pos"></param> |
3105 | public void UpdateGroupPosition(Vector3 pos) | 3171 | public void UpdateGroupPosition(Vector3 pos) |
3106 | { | 3172 | { |
3173 | foreach (SceneObjectPart part in Children.Values) | ||
3174 | { | ||
3175 | part.StoreUndoState(); | ||
3176 | } | ||
3107 | if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) | 3177 | if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) |
3108 | { | 3178 | { |
3109 | if (IsAttachment) | 3179 | if (IsAttachment) |
3110 | { | 3180 | { |
3111 | m_rootPart.AttachedPos = pos; | 3181 | m_rootPart.AttachedPos = pos; |
3112 | } | 3182 | } |
3113 | 3183 | if (RootPart.GetStatusSandbox()) | |
3184 | { | ||
3185 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, pos) > 10) | ||
3186 | { | ||
3187 | RootPart.ScriptSetPhysicsStatus(false); | ||
3188 | pos = AbsolutePosition; | ||
3189 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), | ||
3190 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); | ||
3191 | } | ||
3192 | } | ||
3114 | AbsolutePosition = pos; | 3193 | AbsolutePosition = pos; |
3115 | 3194 | ||
3116 | HasGroupChanged = true; | 3195 | HasGroupChanged = true; |
@@ -3129,7 +3208,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3129 | public void UpdateSinglePosition(Vector3 pos, uint localID) | 3208 | public void UpdateSinglePosition(Vector3 pos, uint localID) |
3130 | { | 3209 | { |
3131 | SceneObjectPart part = GetChildPart(localID); | 3210 | SceneObjectPart part = GetChildPart(localID); |
3132 | 3211 | foreach (SceneObjectPart parts in Children.Values) | |
3212 | { | ||
3213 | parts.StoreUndoState(); | ||
3214 | } | ||
3133 | if (part != null) | 3215 | if (part != null) |
3134 | { | 3216 | { |
3135 | if (part.UUID == m_rootPart.UUID) | 3217 | if (part.UUID == m_rootPart.UUID) |
@@ -3151,6 +3233,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3151 | /// <param name="pos"></param> | 3233 | /// <param name="pos"></param> |
3152 | private void UpdateRootPosition(Vector3 pos) | 3234 | private void UpdateRootPosition(Vector3 pos) |
3153 | { | 3235 | { |
3236 | foreach (SceneObjectPart part in Children.Values) | ||
3237 | { | ||
3238 | part.StoreUndoState(); | ||
3239 | } | ||
3154 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | 3240 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); |
3155 | Vector3 oldPos = | 3241 | Vector3 oldPos = |
3156 | new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, | 3242 | new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, |
@@ -3195,6 +3281,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3195 | /// <param name="rot"></param> | 3281 | /// <param name="rot"></param> |
3196 | public void UpdateGroupRotationR(Quaternion rot) | 3282 | public void UpdateGroupRotationR(Quaternion rot) |
3197 | { | 3283 | { |
3284 | foreach (SceneObjectPart parts in Children.Values) | ||
3285 | { | ||
3286 | parts.StoreUndoState(); | ||
3287 | } | ||
3198 | m_rootPart.UpdateRotation(rot); | 3288 | m_rootPart.UpdateRotation(rot); |
3199 | 3289 | ||
3200 | PhysicsActor actor = m_rootPart.PhysActor; | 3290 | PhysicsActor actor = m_rootPart.PhysActor; |
@@ -3215,6 +3305,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3215 | /// <param name="rot"></param> | 3305 | /// <param name="rot"></param> |
3216 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) | 3306 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) |
3217 | { | 3307 | { |
3308 | foreach (SceneObjectPart parts in Children.Values) | ||
3309 | { | ||
3310 | parts.StoreUndoState(); | ||
3311 | } | ||
3218 | m_rootPart.UpdateRotation(rot); | 3312 | m_rootPart.UpdateRotation(rot); |
3219 | 3313 | ||
3220 | PhysicsActor actor = m_rootPart.PhysActor; | 3314 | PhysicsActor actor = m_rootPart.PhysActor; |
@@ -3238,6 +3332,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3238 | public void UpdateSingleRotation(Quaternion rot, uint localID) | 3332 | public void UpdateSingleRotation(Quaternion rot, uint localID) |
3239 | { | 3333 | { |
3240 | SceneObjectPart part = GetChildPart(localID); | 3334 | SceneObjectPart part = GetChildPart(localID); |
3335 | foreach (SceneObjectPart parts in Children.Values) | ||
3336 | { | ||
3337 | parts.StoreUndoState(); | ||
3338 | } | ||
3241 | if (part != null) | 3339 | if (part != null) |
3242 | { | 3340 | { |
3243 | if (part.UUID == m_rootPart.UUID) | 3341 | if (part.UUID == m_rootPart.UUID) |
@@ -3268,8 +3366,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3268 | } | 3366 | } |
3269 | else | 3367 | else |
3270 | { | 3368 | { |
3369 | part.IgnoreUndoUpdate = true; | ||
3271 | part.UpdateRotation(rot); | 3370 | part.UpdateRotation(rot); |
3272 | part.OffsetPosition = pos; | 3371 | part.OffsetPosition = pos; |
3372 | part.IgnoreUndoUpdate = false; | ||
3373 | part.StoreUndoState(); | ||
3273 | } | 3374 | } |
3274 | } | 3375 | } |
3275 | } | 3376 | } |
@@ -3283,6 +3384,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3283 | Quaternion axRot = rot; | 3384 | Quaternion axRot = rot; |
3284 | Quaternion oldParentRot = m_rootPart.RotationOffset; | 3385 | Quaternion oldParentRot = m_rootPart.RotationOffset; |
3285 | 3386 | ||
3387 | m_rootPart.StoreUndoState(); | ||
3286 | m_rootPart.UpdateRotation(rot); | 3388 | m_rootPart.UpdateRotation(rot); |
3287 | if (m_rootPart.PhysActor != null) | 3389 | if (m_rootPart.PhysActor != null) |
3288 | { | 3390 | { |
@@ -3291,23 +3393,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
3291 | } | 3393 | } |
3292 | 3394 | ||
3293 | lockPartsForRead(true); | 3395 | lockPartsForRead(true); |
3396 | |||
3397 | foreach (SceneObjectPart prim in m_parts.Values) | ||
3294 | { | 3398 | { |
3295 | foreach (SceneObjectPart prim in m_parts.Values) | 3399 | if (prim.UUID != m_rootPart.UUID) |
3296 | { | 3400 | { |
3297 | if (prim.UUID != m_rootPart.UUID) | 3401 | prim.IgnoreUndoUpdate = true; |
3298 | { | 3402 | Vector3 axPos = prim.OffsetPosition; |
3299 | Vector3 axPos = prim.OffsetPosition; | 3403 | axPos *= oldParentRot; |
3300 | axPos *= oldParentRot; | 3404 | axPos *= Quaternion.Inverse(axRot); |
3301 | axPos *= Quaternion.Inverse(axRot); | 3405 | prim.OffsetPosition = axPos; |
3302 | prim.OffsetPosition = axPos; | 3406 | Quaternion primsRot = prim.RotationOffset; |
3303 | Quaternion primsRot = prim.RotationOffset; | 3407 | Quaternion newRot = primsRot * oldParentRot; |
3304 | Quaternion newRot = primsRot * oldParentRot; | 3408 | newRot *= Quaternion.Inverse(axRot); |
3305 | newRot *= Quaternion.Inverse(axRot); | 3409 | prim.RotationOffset = newRot; |
3306 | prim.RotationOffset = newRot; | 3410 | prim.ScheduleTerseUpdate(); |
3307 | prim.ScheduleTerseUpdate(); | 3411 | } |
3308 | } | 3412 | } |
3413 | |||
3414 | foreach (SceneObjectPart childpart in Children.Values) | ||
3415 | { | ||
3416 | if (childpart != m_rootPart) | ||
3417 | { | ||
3418 | childpart.IgnoreUndoUpdate = false; | ||
3419 | childpart.StoreUndoState(); | ||
3309 | } | 3420 | } |
3310 | } | 3421 | } |
3422 | |||
3311 | lockPartsForRead(false); | 3423 | lockPartsForRead(false); |
3312 | 3424 | ||
3313 | m_rootPart.ScheduleTerseUpdate(); | 3425 | m_rootPart.ScheduleTerseUpdate(); |