aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs349
2 files changed, 186 insertions, 169 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6f46a92..f0364db 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -657,6 +657,9 @@ namespace OpenSim.Region.Framework.Scenes
657 } 657 }
658 } 658 }
659 659
660 if(!m_scene.IsRunning)
661 return sog;
662
660 if (root.KeyframeMotion != null) 663 if (root.KeyframeMotion != null)
661 root.KeyframeMotion.StartCrossingCheck(); 664 root.KeyframeMotion.StartCrossingCheck();
662 665
@@ -3018,12 +3021,13 @@ namespace OpenSim.Region.Framework.Scenes
3018 3021
3019 // If we somehow got here to updating the SOG and its root part is not scheduled for update, 3022 // If we somehow got here to updating the SOG and its root part is not scheduled for update,
3020 // check to see if the physical position or rotation warrant an update. 3023 // check to see if the physical position or rotation warrant an update.
3024/*
3021 if (m_rootPart.UpdateFlag == UpdateRequired.NONE) 3025 if (m_rootPart.UpdateFlag == UpdateRequired.NONE)
3022 { 3026 {
3023 // rootpart SendScheduledUpdates will check if a update is needed 3027 // rootpart SendScheduledUpdates will check if a update is needed
3024 m_rootPart.UpdateFlag = UpdateRequired.TERSE; 3028 m_rootPart.UpdateFlag = UpdateRequired.TERSE;
3025 } 3029 }
3026 3030*/
3027 if (IsAttachment) 3031 if (IsAttachment)
3028 { 3032 {
3029 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar); 3033 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 0bf3c1d..0370c41 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -238,12 +238,6 @@ namespace OpenSim.Region.Framework.Scenes
238 /// </remarks> 238 /// </remarks>
239 public bool SoundQueueing { get; set; } 239 public bool SoundQueueing { get; set; }
240 240
241 public uint TimeStampFull;
242
243 public uint TimeStampLastActivity; // Will be used for AutoReturn
244
245 public uint TimeStampTerse;
246
247 [XmlIgnore] 241 [XmlIgnore]
248 public Quaternion AttachRotation = Quaternion.Identity; 242 public Quaternion AttachRotation = Quaternion.Identity;
249 243
@@ -1219,6 +1213,7 @@ namespace OpenSim.Region.Framework.Scenes
1219 } 1213 }
1220 1214
1221 public UpdateRequired UpdateFlag { get; set; } 1215 public UpdateRequired UpdateFlag { get; set; }
1216 private object UpdateFlagLock = new object();
1222 1217
1223 /// <summary> 1218 /// <summary>
1224 /// Used for media on a prim. 1219 /// Used for media on a prim.
@@ -1641,8 +1636,10 @@ namespace OpenSim.Region.Framework.Scenes
1641 PhysActor.SetMaterial((int)value); 1636 PhysActor.SetMaterial((int)value);
1642 } 1637 }
1643 if(ParentGroup != null) 1638 if(ParentGroup != null)
1639 {
1644 ParentGroup.HasGroupChanged = true; 1640 ParentGroup.HasGroupChanged = true;
1645 ScheduleFullUpdateIfNone(); 1641 ScheduleFullUpdate();
1642 }
1646 } 1643 }
1647 } 1644 }
1648 } 1645 }
@@ -1730,7 +1727,12 @@ namespace OpenSim.Region.Framework.Scenes
1730 1727
1731 public byte PhysicsShapeType 1728 public byte PhysicsShapeType
1732 { 1729 {
1733 get { return m_physicsShapeType; } 1730 get
1731 {
1732// if (PhysActor != null)
1733// m_physicsShapeType = PhysActor.PhysicsShapeType;
1734 return m_physicsShapeType;
1735 }
1734 set 1736 set
1735 { 1737 {
1736 byte oldv = m_physicsShapeType; 1738 byte oldv = m_physicsShapeType;
@@ -1781,10 +1783,12 @@ namespace OpenSim.Region.Framework.Scenes
1781 { 1783 {
1782 m_density = value; 1784 m_density = value;
1783 1785
1784 ScheduleFullUpdateIfNone();
1785 1786
1786 if (ParentGroup != null) 1787 if (ParentGroup != null)
1788 {
1787 ParentGroup.HasGroupChanged = true; 1789 ParentGroup.HasGroupChanged = true;
1790 ScheduleFullUpdate();
1791 }
1788 1792
1789 PhysicsActor pa = PhysActor; 1793 PhysicsActor pa = PhysActor;
1790 if (pa != null) 1794 if (pa != null)
@@ -1802,10 +1806,11 @@ namespace OpenSim.Region.Framework.Scenes
1802 { 1806 {
1803 m_gravitymod = value; 1807 m_gravitymod = value;
1804 1808
1805 ScheduleFullUpdateIfNone();
1806
1807 if (ParentGroup != null) 1809 if (ParentGroup != null)
1810 {
1808 ParentGroup.HasGroupChanged = true; 1811 ParentGroup.HasGroupChanged = true;
1812 ScheduleFullUpdate();
1813 }
1809 1814
1810 PhysicsActor pa = PhysActor; 1815 PhysicsActor pa = PhysActor;
1811 if (pa != null) 1816 if (pa != null)
@@ -1823,10 +1828,11 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1828 {
1824 m_friction = value; 1829 m_friction = value;
1825 1830
1826 ScheduleFullUpdateIfNone();
1827
1828 if (ParentGroup != null) 1831 if (ParentGroup != null)
1832 {
1829 ParentGroup.HasGroupChanged = true; 1833 ParentGroup.HasGroupChanged = true;
1834 ScheduleFullUpdate();
1835 }
1830 1836
1831 PhysicsActor pa = PhysActor; 1837 PhysicsActor pa = PhysActor;
1832 if (pa != null) 1838 if (pa != null)
@@ -1844,10 +1850,11 @@ namespace OpenSim.Region.Framework.Scenes
1844 { 1850 {
1845 m_bounce = value; 1851 m_bounce = value;
1846 1852
1847 ScheduleFullUpdateIfNone();
1848
1849 if (ParentGroup != null) 1853 if (ParentGroup != null)
1854 {
1850 ParentGroup.HasGroupChanged = true; 1855 ParentGroup.HasGroupChanged = true;
1856 ScheduleFullUpdate();
1857 }
1851 1858
1852 PhysicsActor pa = PhysActor; 1859 PhysicsActor pa = PhysActor;
1853 if (pa != null) 1860 if (pa != null)
@@ -1876,7 +1883,8 @@ namespace OpenSim.Region.Framework.Scenes
1876 /// </summary> 1883 /// </summary>
1877 public void ClearUpdateSchedule() 1884 public void ClearUpdateSchedule()
1878 { 1885 {
1879 UpdateFlag = UpdateRequired.NONE; 1886 lock(UpdateFlagLock)
1887 UpdateFlag = UpdateRequired.NONE;
1880 } 1888 }
1881 1889
1882 /// <summary> 1890 /// <summary>
@@ -3239,17 +3247,6 @@ namespace OpenSim.Region.Framework.Scenes
3239 APIDActive = false; 3247 APIDActive = false;
3240 } 3248 }
3241 3249
3242 public void ScheduleFullUpdateIfNone()
3243 {
3244 if (ParentGroup == null)
3245 return;
3246
3247// ??? ParentGroup.HasGroupChanged = true;
3248
3249 if (UpdateFlag != UpdateRequired.FULL)
3250 ScheduleFullUpdate();
3251 }
3252
3253 /// <summary> 3250 /// <summary>
3254 /// Schedules this prim for a full update 3251 /// Schedules this prim for a full update
3255 /// </summary> 3252 /// </summary>
@@ -3260,30 +3257,21 @@ namespace OpenSim.Region.Framework.Scenes
3260 if (ParentGroup == null) 3257 if (ParentGroup == null)
3261 return; 3258 return;
3262 3259
3263 ParentGroup.QueueForUpdateCheck(); 3260 lock(UpdateFlagLock)
3264
3265 int timeNow = Util.UnixTimeSinceEpoch();
3266
3267 // If multiple updates are scheduled on the same second, we still need to perform all of them
3268 // So we'll force the issue by bumping up the timestamp so that later processing sees these need
3269 // to be performed.
3270 if (timeNow <= TimeStampFull)
3271 { 3261 {
3272 TimeStampFull += 1; 3262 ParentGroup.QueueForUpdateCheck(); // just in case
3273 } 3263 if(UpdateFlag != UpdateRequired.FULL)
3274 else 3264 {
3275 { 3265 UpdateFlag = UpdateRequired.FULL;
3276 TimeStampFull = (uint)timeNow;
3277 }
3278
3279 UpdateFlag = UpdateRequired.FULL;
3280 3266
3281 // m_log.DebugFormat( 3267 // m_log.DebugFormat(
3282 // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", 3268 // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
3283 // UUID, Name, TimeStampFull); 3269 // UUID, Name, TimeStampFull);
3284 3270
3285 if (ParentGroup.Scene != null) 3271 if (ParentGroup.Scene != null)
3286 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); 3272 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
3273 }
3274 }
3287 } 3275 }
3288 3276
3289 /// <summary> 3277 /// <summary>
@@ -3304,21 +3292,23 @@ namespace OpenSim.Region.Framework.Scenes
3304 return; 3292 return;
3305 } 3293 }
3306 3294
3307 if (UpdateFlag == UpdateRequired.NONE) 3295 lock(UpdateFlagLock)
3308 { 3296 {
3309 ParentGroup.HasGroupChanged = true; 3297 if (UpdateFlag == UpdateRequired.NONE)
3310 ParentGroup.QueueForUpdateCheck(); 3298 {
3299 ParentGroup.HasGroupChanged = true;
3300 ParentGroup.QueueForUpdateCheck();
3311 3301
3312 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); 3302 UpdateFlag = UpdateRequired.TERSE;
3313 UpdateFlag = UpdateRequired.TERSE;
3314 3303
3315 // m_log.DebugFormat( 3304 // m_log.DebugFormat(
3316 // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", 3305 // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}",
3317 // UUID, Name, TimeStampTerse); 3306 // UUID, Name, TimeStampTerse);
3318 } 3307 }
3319 3308
3320 if (ParentGroup.Scene != null) 3309 if (ParentGroup.Scene != null)
3321 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); 3310 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false);
3311 }
3322 } 3312 }
3323 3313
3324 public void ScriptSetPhysicsStatus(bool UsePhysics) 3314 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -3362,12 +3352,15 @@ namespace OpenSim.Region.Framework.Scenes
3362 return; 3352 return;
3363 3353
3364 // Update the "last" values 3354 // Update the "last" values
3365 m_lastPosition = AbsolutePosition; 3355 lock(UpdateFlagLock)
3366 m_lastRotation = RotationOffset; 3356 {
3367 m_lastVelocity = Velocity; 3357 m_lastPosition = AbsolutePosition;
3368 m_lastAcceleration = Acceleration; 3358 m_lastRotation = RotationOffset;
3369 m_lastAngularVelocity = AngularVelocity; 3359 m_lastVelocity = Velocity;
3370 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3360 m_lastAcceleration = Acceleration;
3361 m_lastAngularVelocity = AngularVelocity;
3362 m_lastUpdateSentTime = Util.GetTimeStampMS();
3363 }
3371 3364
3372 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3365 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3373 { 3366 {
@@ -3381,12 +3374,15 @@ namespace OpenSim.Region.Framework.Scenes
3381 return; 3374 return;
3382 3375
3383 // Update the "last" values 3376 // Update the "last" values
3384 m_lastPosition = AbsolutePosition; 3377 lock(UpdateFlagLock)
3385 m_lastRotation = RotationOffset; 3378 {
3386 m_lastVelocity = Velocity; 3379 m_lastPosition = AbsolutePosition;
3387 m_lastAcceleration = Acceleration; 3380 m_lastRotation = RotationOffset;
3388 m_lastAngularVelocity = AngularVelocity; 3381 m_lastVelocity = Velocity;
3389 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3382 m_lastAcceleration = Acceleration;
3383 m_lastAngularVelocity = AngularVelocity;
3384 m_lastUpdateSentTime = Util.GetTimeStampMS();
3385 }
3390 3386
3391 if (ParentGroup.IsAttachment) 3387 if (ParentGroup.IsAttachment)
3392 { 3388 {
@@ -3442,108 +3438,118 @@ namespace OpenSim.Region.Framework.Scenes
3442 /// Tell all the prims which have had updates scheduled 3438 /// Tell all the prims which have had updates scheduled
3443 /// </summary> 3439 /// </summary>
3444 public void SendScheduledUpdates() 3440 public void SendScheduledUpdates()
3445 { 3441 {
3446 switch (UpdateFlag) 3442 UpdateRequired currentUpdate;
3443 lock(UpdateFlagLock)
3444 {
3445 currentUpdate = UpdateFlag;
3446 ClearUpdateSchedule();
3447 }
3448
3449 switch (currentUpdate)
3447 { 3450 {
3448 case UpdateRequired.NONE: 3451 case UpdateRequired.NONE:
3449 ClearUpdateSchedule();
3450 break; 3452 break;
3451 3453
3452 case UpdateRequired.TERSE: 3454 case UpdateRequired.TERSE:
3453
3454 ClearUpdateSchedule();
3455 bool needupdate = true; 3455 bool needupdate = true;
3456 double now = Util.GetTimeStampMS(); 3456 lock(UpdateFlagLock)
3457 Vector3 curvel = Velocity;
3458 Vector3 curacc = Acceleration;
3459 Vector3 angvel = AngularVelocity;
3460
3461 while(true) // just to avoid ugly goto
3462 { 3457 {
3463 double elapsed = now - m_lastUpdateSentTime; 3458 double now = Util.GetTimeStampMS();
3464 if (elapsed > TIME_MS_TOLERANCE) 3459 Vector3 curvel = Velocity;
3465 break; 3460 Vector3 curacc = Acceleration;
3461 Vector3 angvel = AngularVelocity;
3466 3462
3467 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE || 3463 while(true) // just to avoid ugly goto
3468 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE || 3464 {
3469 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE) 3465 double elapsed = now - m_lastUpdateSentTime;
3470 break; 3466 if (elapsed > TIME_MS_TOLERANCE)
3467 break;
3471 3468
3472 // velocity change is also direction not only norm) 3469 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
3473 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || 3470 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
3474 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || 3471 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
3475 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE) 3472 break;
3476 break;
3477
3478 float vx = Math.Abs(curvel.X);
3479 if(vx > 128.0)
3480 break;
3481 float vy = Math.Abs(curvel.Y);
3482 if(vy > 128.0)
3483 break;
3484 float vz = Math.Abs(curvel.Z);
3485 if(vz > 128.0)
3486 break;
3487 3473
3488 if ( 3474 // velocity change is also direction not only norm)
3489 vx < VELOCITY_TOLERANCE && 3475 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3490 vy < VELOCITY_TOLERANCE && 3476 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3491 vz < VELOCITY_TOLERANCE 3477 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
3492 )
3493 {
3494 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3495 break; 3478 break;
3479
3480 float vx = Math.Abs(curvel.X);
3481 if(vx > 128.0)
3482 break;
3483 float vy = Math.Abs(curvel.Y);
3484 if(vy > 128.0)
3485 break;
3486 float vz = Math.Abs(curvel.Z);
3487 if(vz > 128.0)
3488 break;
3489
3490 if (
3491 vx < VELOCITY_TOLERANCE &&
3492 vy < VELOCITY_TOLERANCE &&
3493 vz < VELOCITY_TOLERANCE
3494 )
3495 {
3496 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3497 break;
3496 3498
3497 if (vx < 1e-4 && 3499 if (vx < 1e-4 &&
3498 vy < 1e-4 && 3500 vy < 1e-4 &&
3499 vz < 1e-4 && 3501 vz < 1e-4 &&
3500 ( 3502 (
3501 Math.Abs(m_lastVelocity.X) > 1e-4 || 3503 Math.Abs(m_lastVelocity.X) > 1e-4 ||
3502 Math.Abs(m_lastVelocity.Y) > 1e-4 || 3504 Math.Abs(m_lastVelocity.Y) > 1e-4 ||
3503 Math.Abs(m_lastVelocity.Z) > 1e-4 3505 Math.Abs(m_lastVelocity.Z) > 1e-4
3504 )) 3506 ))
3507 break;
3508 }
3509
3510 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE ||
3511 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE ||
3512 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE)
3505 break; 3513 break;
3506 }
3507 3514
3508 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE || 3515 // viewer interpolators have a limit of 128m/s
3509 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE || 3516 float ax = Math.Abs(angvel.X);
3510 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE) 3517 if(ax > 64.0)
3511 break; 3518 break;
3519 float ay = Math.Abs(angvel.Y);
3520 if(ay > 64.0)
3521 break;
3522 float az = Math.Abs(angvel.Z);
3523 if(az > 64.0)
3524 break;
3512 3525
3513 // viewer interpolators have a limit of 128m/s 3526 if (
3514 float ax = Math.Abs(angvel.X); 3527 ax < VELOCITY_TOLERANCE &&
3515 if(ax > 64.0) 3528 ay < VELOCITY_TOLERANCE &&
3516 break; 3529 az < VELOCITY_TOLERANCE &&
3517 float ay = Math.Abs(angvel.Y); 3530 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3518 if(ay > 64.0) 3531 )
3519 break; 3532 break;
3520 float az = Math.Abs(angvel.Z); 3533
3521 if(az > 64.0) 3534 needupdate = false;
3522 break; 3535 break;
3536 }
3523 3537
3524 if ( 3538 if(needupdate)
3525 ax < VELOCITY_TOLERANCE && 3539 {
3526 ay < VELOCITY_TOLERANCE &&
3527 az < VELOCITY_TOLERANCE &&
3528 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3529 )
3530 break;
3531 3540
3532 needupdate = false; 3541 // Update the "last" values
3533 break; 3542 m_lastPosition = AbsolutePosition;
3543 m_lastRotation = RotationOffset;
3544 m_lastVelocity = curvel;
3545 m_lastAcceleration = curacc;
3546 m_lastAngularVelocity = angvel;
3547 m_lastUpdateSentTime = now;
3548 }
3534 } 3549 }
3535 3550
3536 if(needupdate) 3551 if(needupdate)
3537 { 3552 {
3538
3539 // Update the "last" values
3540 m_lastPosition = AbsolutePosition;
3541 m_lastRotation = RotationOffset;
3542 m_lastVelocity = curvel;
3543 m_lastAcceleration = curacc;
3544 m_lastAngularVelocity = angvel;
3545 m_lastUpdateSentTime = now;
3546
3547 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3553 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3548 { 3554 {
3549 SendTerseUpdateToClient(client); 3555 SendTerseUpdateToClient(client);
@@ -3552,7 +3558,6 @@ namespace OpenSim.Region.Framework.Scenes
3552 break; 3558 break;
3553 3559
3554 case UpdateRequired.FULL: 3560 case UpdateRequired.FULL:
3555 ClearUpdateSchedule();
3556 SendFullUpdateToAllClientsInternal(); 3561 SendFullUpdateToAllClientsInternal();
3557 break; 3562 break;
3558 } 3563 }
@@ -3567,15 +3572,19 @@ namespace OpenSim.Region.Framework.Scenes
3567 if (ParentGroup == null || ParentGroup.Scene == null) 3572 if (ParentGroup == null || ParentGroup.Scene == null)
3568 return; 3573 return;
3569 3574
3570 ClearUpdateSchedule(); 3575 lock(UpdateFlagLock)
3576 {
3577 if(UpdateFlag != UpdateRequired.NONE)
3578 return;
3571 3579
3572 // Update the "last" values 3580 // Update the "last" values
3573 m_lastPosition = AbsolutePosition; 3581 m_lastPosition = AbsolutePosition;
3574 m_lastRotation = RotationOffset; 3582 m_lastRotation = RotationOffset;
3575 m_lastVelocity = Velocity; 3583 m_lastVelocity = Velocity;
3576 m_lastAcceleration = Acceleration; 3584 m_lastAcceleration = Acceleration;
3577 m_lastAngularVelocity = AngularVelocity; 3585 m_lastAngularVelocity = AngularVelocity;
3578 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3586 m_lastUpdateSentTime = Util.GetTimeStampMS();
3587 }
3579 3588
3580 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3589 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3581 { 3590 {
@@ -3588,15 +3597,19 @@ namespace OpenSim.Region.Framework.Scenes
3588 if (ParentGroup == null || ParentGroup.Scene == null) 3597 if (ParentGroup == null || ParentGroup.Scene == null)
3589 return; 3598 return;
3590 3599
3591 ClearUpdateSchedule(); 3600 lock(UpdateFlagLock)
3601 {
3602 if(UpdateFlag != UpdateRequired.NONE)
3603 return;
3592 3604
3593 // Update the "last" values 3605 // Update the "last" values
3594 m_lastPosition = AbsolutePosition; 3606 m_lastPosition = AbsolutePosition;
3595 m_lastRotation = RotationOffset; 3607 m_lastRotation = RotationOffset;
3596 m_lastVelocity = Velocity; 3608 m_lastVelocity = Velocity;
3597 m_lastAcceleration = Acceleration; 3609 m_lastAcceleration = Acceleration;
3598 m_lastAngularVelocity = AngularVelocity; 3610 m_lastAngularVelocity = AngularVelocity;
3599 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3611 m_lastUpdateSentTime = Util.GetTimeStampMS();
3612 }
3600 3613
3601 if (ParentGroup.IsAttachment) 3614 if (ParentGroup.IsAttachment)
3602 { 3615 {