aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs448
1 files changed, 266 insertions, 182 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6c035f0..c549f5c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -68,22 +68,6 @@ namespace OpenSim.Region.Framework.Scenes
68 POSITION = 32768 68 POSITION = 32768
69 } 69 }
70 70
71 // I don't really know where to put this except here.
72 // Can't access the OpenSim.Region.ScriptEngine.Common.LSL_BaseClass.Changed constants
73 [Flags]
74 public enum ExtraParamType
75 {
76 Something1 = 1,
77 Something2 = 2,
78 Something3 = 4,
79 Something4 = 8,
80 Flexible = 16,
81 Light = 32,
82 Sculpt = 48,
83 Something5 = 64,
84 Something6 = 128
85 }
86
87 [Flags] 71 [Flags]
88 public enum TextureAnimFlags : byte 72 public enum TextureAnimFlags : byte
89 { 73 {
@@ -109,13 +93,6 @@ namespace OpenSim.Region.Framework.Scenes
109 SCULPT = 7 93 SCULPT = 7
110 } 94 }
111 95
112 public enum UpdateRequired : byte
113 {
114 NONE = 0,
115 TERSE = 1,
116 FULL = 2
117 }
118
119 #endregion Enumerations 96 #endregion Enumerations
120 97
121 public class SceneObjectPart : ISceneEntity 98 public class SceneObjectPart : ISceneEntity
@@ -182,10 +159,13 @@ namespace OpenSim.Region.Framework.Scenes
182 { 159 {
183 get 160 get
184 { 161 {
185 return 162 // assume SitTargetOrientation is normalized (as needed elsewhere)
186 !(SitTargetPosition == Vector3.Zero 163 if( SitTargetPosition != Vector3.Zero ||
187 && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion 164 SitTargetOrientation.X != 0f ||
188 || (SitTargetOrientation.W == 0f && SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f ))); // Invalid Quaternion 165 SitTargetOrientation.Y != 0f ||
166 SitTargetOrientation.Z != 0f)
167 return true;
168 return false;
189 } 169 }
190 } 170 }
191 171
@@ -1212,7 +1192,18 @@ namespace OpenSim.Region.Framework.Scenes
1212 return a * b; 1192 return a * b;
1213 } 1193 }
1214 1194
1215 public UpdateRequired UpdateFlag { get; set; } 1195 public PrimUpdateFlags UpdateFlag { get; set; }
1196
1197 public PrimUpdateFlags GetAndClearUpdateFlag()
1198 {
1199 lock(UpdateFlagLock)
1200 {
1201 PrimUpdateFlags ret = UpdateFlag;
1202 UpdateFlag = PrimUpdateFlags.None;
1203 return ret;
1204 }
1205 }
1206
1216 private object UpdateFlagLock = new object(); 1207 private object UpdateFlagLock = new object();
1217 1208
1218 /// <summary> 1209 /// <summary>
@@ -1503,11 +1494,16 @@ namespace OpenSim.Region.Framework.Scenes
1503 } 1494 }
1504 set 1495 set
1505 { 1496 {
1497 UUID old = m_collisionSound;
1498
1506 m_collisionSoundType = value; 1499 m_collisionSoundType = value;
1507 if (value == -1) 1500 if (value == -1)
1508 m_collisionSound = invalidCollisionSoundUUID; 1501 m_collisionSound = invalidCollisionSoundUUID;
1509 else if (value == 0) 1502 else if (value == 0)
1510 m_collisionSound = UUID.Zero; 1503 m_collisionSound = UUID.Zero;
1504
1505 if(m_collisionSound != old && ParentGroup != null)
1506 ParentGroup.HasGroupChanged = true;
1511 } 1507 }
1512 } 1508 }
1513 1509
@@ -1516,6 +1512,7 @@ namespace OpenSim.Region.Framework.Scenes
1516 get { return m_collisionSound; } 1512 get { return m_collisionSound; }
1517 set 1513 set
1518 { 1514 {
1515 UUID olds = m_collisionSound;
1519 m_collisionSound = value; 1516 m_collisionSound = value;
1520 1517
1521 if (value == invalidCollisionSoundUUID) 1518 if (value == invalidCollisionSoundUUID)
@@ -1525,13 +1522,24 @@ namespace OpenSim.Region.Framework.Scenes
1525 else 1522 else
1526 m_collisionSoundType = 1; 1523 m_collisionSoundType = 1;
1527 1524
1525 if(m_collisionSound != olds && ParentGroup != null)
1526 ParentGroup.HasGroupChanged = true;
1528 } 1527 }
1529 } 1528 }
1530 1529
1531 public float CollisionSoundVolume 1530 public float CollisionSoundVolume
1532 { 1531 {
1533 get { return m_collisionSoundVolume; } 1532 get { return m_collisionSoundVolume; }
1534 set { m_collisionSoundVolume = value; } 1533 set
1534 {
1535 float oldvalue = m_collisionSoundVolume;
1536 if(value >= 0)
1537 m_collisionSoundVolume = value;
1538 else
1539 m_collisionSoundVolume = 0.0f;
1540 if(m_collisionSoundVolume != oldvalue && ParentGroup != null)
1541 ParentGroup.HasGroupChanged = true;
1542 }
1535 } 1543 }
1536 1544
1537 public float Buoyancy 1545 public float Buoyancy
@@ -1884,7 +1892,7 @@ namespace OpenSim.Region.Framework.Scenes
1884 public void ClearUpdateSchedule() 1892 public void ClearUpdateSchedule()
1885 { 1893 {
1886 lock(UpdateFlagLock) 1894 lock(UpdateFlagLock)
1887 UpdateFlag = UpdateRequired.NONE; 1895 UpdateFlag = PrimUpdateFlags.None;
1888 } 1896 }
1889 1897
1890 /// <summary> 1898 /// <summary>
@@ -3276,40 +3284,27 @@ namespace OpenSim.Region.Framework.Scenes
3276 { 3284 {
3277// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); 3285// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
3278 3286
3279 if (ParentGroup == null) 3287 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.Scene == null)
3280 return;
3281 if (ParentGroup.Scene == null)
3282 return; 3288 return;
3283 3289
3284 if(ParentGroup.Scene.GetNumberOfClients() == 0) 3290 if(ParentGroup.Scene.GetNumberOfClients() == 0)
3285 return; 3291 return;
3286 3292
3287 ParentGroup.QueueForUpdateCheck(); // just in case 3293 ParentGroup.QueueForUpdateCheck(); // just in case
3288 3294
3289 lock(UpdateFlagLock) 3295 lock(UpdateFlagLock)
3290 { 3296 UpdateFlag |= PrimUpdateFlags.FullUpdate;
3291 if(UpdateFlag != UpdateRequired.FULL)
3292 {
3293 UpdateFlag = UpdateRequired.FULL;
3294 3297
3295 // m_log.DebugFormat(
3296 // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
3297 // UUID, Name, TimeStampFull);
3298
3299 }
3300 }
3301 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); 3298 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
3302 } 3299 }
3303 3300
3304 /// <summary> 3301 /// <summary>
3305 /// Schedule a terse update for this prim. Terse updates only send position, 3302 /// Schedule a terse update for this prim. Terse updates only send position,
3306 /// rotation, velocity and rotational velocity information. WRONG!!!! 3303 /// rotation, velocity and rotational velocity information.
3307 /// </summary> 3304 /// </summary>
3308 public void ScheduleTerseUpdate() 3305 public void ScheduleTerseUpdate()
3309 { 3306 {
3310 if (ParentGroup == null) 3307 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.Scene == null)
3311 return;
3312 if (ParentGroup.Scene == null)
3313 return; 3308 return;
3314 3309
3315 ParentGroup.HasGroupChanged = true; 3310 ParentGroup.HasGroupChanged = true;
@@ -3317,28 +3312,47 @@ namespace OpenSim.Region.Framework.Scenes
3317 if(ParentGroup.Scene.GetNumberOfClients() == 0) 3312 if(ParentGroup.Scene.GetNumberOfClients() == 0)
3318 return; 3313 return;
3319 3314
3320 // This was pulled from SceneViewer. Attachments always receive full updates. 3315 ParentGroup.QueueForUpdateCheck();
3321 // This is needed because otherwise if only the root prim changes position, then 3316
3322 // it looks as if the entire object has moved (including the other prims). 3317 bool isfull = false;
3323 if (ParentGroup.IsAttachment) 3318 lock (UpdateFlagLock)
3324 { 3319 {
3325 ScheduleFullUpdate(); 3320 if (ParentGroup.IsAttachment)
3326 return; 3321 {
3322 UpdateFlag |= PrimUpdateFlags.FullUpdate;
3323 isfull = true;
3324 }
3325 else
3326 UpdateFlag |= PrimUpdateFlags.TerseUpdate;
3327 } 3327 }
3328 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
3329 }
3330
3331 public void ScheduleUpdate(PrimUpdateFlags update)
3332 {
3333 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.Scene == null)
3334 return;
3335
3336 ParentGroup.HasGroupChanged = true;
3337
3338 if (ParentGroup.Scene.GetNumberOfClients() == 0)
3339 return;
3328 3340
3329 ParentGroup.QueueForUpdateCheck(); 3341 ParentGroup.QueueForUpdateCheck();
3330 lock(UpdateFlagLock) 3342
3343 bool isfull = false;
3344 lock (UpdateFlagLock)
3331 { 3345 {
3332 if (UpdateFlag == UpdateRequired.NONE) 3346 if (ParentGroup.IsAttachment)
3333 { 3347 {
3334 UpdateFlag = UpdateRequired.TERSE; 3348 UpdateFlag |= update | PrimUpdateFlags.FullUpdate;
3335 3349 isfull = true;
3336 // m_log.DebugFormat(
3337 // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1}",
3338 // UUID, Name);
3339 } 3350 }
3351 else
3352 UpdateFlag |= update;
3340 } 3353 }
3341 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); 3354
3355 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
3342 } 3356 }
3343 3357
3344 public void ScriptSetPhysicsStatus(bool UsePhysics) 3358 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -3364,7 +3378,7 @@ namespace OpenSim.Region.Framework.Scenes
3364 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 3378 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3365 if (sp != null) 3379 if (sp != null)
3366 { 3380 {
3367 sp.SendAttachmentUpdate(this, UpdateRequired.FULL); 3381 sp.SendAttachmentUpdate(this, PrimUpdateFlags.FullUpdate);
3368 } 3382 }
3369 } 3383 }
3370 else 3384 else
@@ -3373,6 +3387,29 @@ namespace OpenSim.Region.Framework.Scenes
3373 } 3387 }
3374 } 3388 }
3375 3389
3390 protected internal void SendFullUpdate(IClientAPI remoteClient, PrimUpdateFlags update)
3391 {
3392 if (ParentGroup == null)
3393 return;
3394
3395 // m_log.DebugFormat(
3396 // "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
3397
3398
3399 if (ParentGroup.IsAttachment)
3400 {
3401 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3402 if (sp != null)
3403 {
3404 sp.SendAttachmentUpdate(this, update);
3405 }
3406 }
3407 else
3408 {
3409 SendUpdateToClient(remoteClient, update);
3410 }
3411 }
3412
3376 /// <summary> 3413 /// <summary>
3377 /// Send a full update for this part to all clients. 3414 /// Send a full update for this part to all clients.
3378 /// </summary> 3415 /// </summary>
@@ -3419,7 +3456,7 @@ namespace OpenSim.Region.Framework.Scenes
3419 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 3456 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3420 if (sp != null) 3457 if (sp != null)
3421 { 3458 {
3422 sp.SendAttachmentUpdate(this, UpdateRequired.FULL); 3459 sp.SendAttachmentUpdate(this, PrimUpdateFlags.FullUpdate);
3423 } 3460 }
3424 } 3461 }
3425 else 3462 else
@@ -3469,136 +3506,109 @@ namespace OpenSim.Region.Framework.Scenes
3469 /// </summary> 3506 /// </summary>
3470 public void SendScheduledUpdates(double now) 3507 public void SendScheduledUpdates(double now)
3471 { 3508 {
3472 bool sendterse = false; 3509 PrimUpdateFlags current;
3473 bool sendfull = false; 3510 lock (UpdateFlagLock)
3474
3475 lock(UpdateFlagLock)
3476 { 3511 {
3477 switch (UpdateFlag) 3512 current = UpdateFlag;
3478 {
3479 case UpdateRequired.NONE:
3480 break;
3481 3513
3482 case UpdateRequired.TERSE: 3514 if (current == PrimUpdateFlags.None)
3483 sendterse = true; 3515 return;
3484 3516
3485 Vector3 curvel = Velocity; 3517 if(current == PrimUpdateFlags.TerseUpdate)
3486 Vector3 curacc = Acceleration; 3518 {
3487 Vector3 angvel = AngularVelocity; 3519 Vector3 curvel = Velocity;
3520 Vector3 curacc = Acceleration;
3521 Vector3 angvel = AngularVelocity;
3488 3522
3489 while(true) // just to avoid ugly goto 3523 while(true) // just to avoid ugly goto
3490 { 3524 {
3491 double elapsed = now - m_lastUpdateSentTime; 3525 double elapsed = now - m_lastUpdateSentTime;
3492 if (elapsed > TIME_MS_TOLERANCE) 3526 if (elapsed > TIME_MS_TOLERANCE)
3493 break; 3527 break;
3494 3528
3495 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE || 3529 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
3496 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE || 3530 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
3497 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE) 3531 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
3498 break; 3532 break;
3499 3533
3500 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || 3534 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3501 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || 3535 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3502 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE) 3536 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
3503 break; 3537 break;
3504 3538
3505 float vx = Math.Abs(curvel.X); 3539 float vx = Math.Abs(curvel.X);
3506 if(vx > 128.0) 3540 if(vx > 128.0)
3507 break; 3541 break;
3508 float vy = Math.Abs(curvel.Y); 3542 float vy = Math.Abs(curvel.Y);
3509 if(vy > 128.0) 3543 if(vy > 128.0)
3510 break; 3544 break;
3511 float vz = Math.Abs(curvel.Z); 3545 float vz = Math.Abs(curvel.Z);
3512 if(vz > 128.0) 3546 if(vz > 128.0)
3513 break; 3547 break;
3514 3548
3515 if ( 3549 if(
3516 vx < VELOCITY_TOLERANCE && 3550 vx < VELOCITY_TOLERANCE &&
3517 vy < VELOCITY_TOLERANCE && 3551 vy < VELOCITY_TOLERANCE &&
3518 vz < VELOCITY_TOLERANCE 3552 vz < VELOCITY_TOLERANCE
3519 ) 3553 )
3520 { 3554 {
3521 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) 3555 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3522 break; 3556 break;
3523 3557 if(vx < 1e-4 &&
3524 if (vx < 1e-4 &&
3525 vy < 1e-4 && 3558 vy < 1e-4 &&
3526 vz < 1e-4 && 3559 vz < 1e-4 &&
3527 ( 3560 (
3528 Math.Abs(m_lastVelocity.X) > 1e-4 || 3561 Math.Abs(m_lastVelocity.X) > 1e-4 ||
3529 Math.Abs(m_lastVelocity.Y) > 1e-4 || 3562 Math.Abs(m_lastVelocity.Y) > 1e-4 ||
3530 Math.Abs(m_lastVelocity.Z) > 1e-4 3563 Math.Abs(m_lastVelocity.Z) > 1e-4
3531 )) 3564 ))
3532 break; 3565 break;
3533 } 3566 }
3534 3567
3535 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > ANGVELOCITY_TOLERANCE || 3568 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > ANGVELOCITY_TOLERANCE ||
3536 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > ANGVELOCITY_TOLERANCE || 3569 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > ANGVELOCITY_TOLERANCE ||
3537 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > ANGVELOCITY_TOLERANCE) 3570 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > ANGVELOCITY_TOLERANCE)
3538 break; 3571 break;
3539 3572
3540 // viewer interpolators have a limit of 64rad/s 3573 // viewer interpolators have a limit of 64rad/s
3541 float ax = Math.Abs(angvel.X); 3574 float ax = Math.Abs(angvel.X);
3542 if(ax > 64.0) 3575 if(ax > 64.0)
3543 break; 3576 break;
3544 float ay = Math.Abs(angvel.Y); 3577 float ay = Math.Abs(angvel.Y);
3545 if(ay > 64.0) 3578 if(ay > 64.0)
3546 break; 3579 break;
3547 float az = Math.Abs(angvel.Z); 3580 float az = Math.Abs(angvel.Z);
3548 if(az > 64.0) 3581 if(az > 64.0)
3549 break; 3582 break;
3550 3583
3551 if ( 3584 if (
3552 ax < ANGVELOCITY_TOLERANCE && 3585 ax < ANGVELOCITY_TOLERANCE &&
3553 ay < ANGVELOCITY_TOLERANCE && 3586 ay < ANGVELOCITY_TOLERANCE &&
3554 az < ANGVELOCITY_TOLERANCE && 3587 az < ANGVELOCITY_TOLERANCE &&
3555 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) 3588 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3556 ) 3589 )
3557 break;
3558
3559 sendterse = false;
3560 break; 3590 break;
3561 } 3591 return;
3562 3592 }
3563 if(sendterse)
3564 {
3565 // Update the "last" values
3566 m_lastPosition = AbsolutePosition;
3567 m_lastRotation = RotationOffset;
3568 m_lastVelocity = curvel;
3569 m_lastAcceleration = curacc;
3570 m_lastAngularVelocity = angvel;
3571 m_lastUpdateSentTime = now;
3572 ClearUpdateSchedule();
3573 }
3574 break;
3575
3576 case UpdateRequired.FULL:
3577 m_lastPosition = AbsolutePosition;
3578 m_lastRotation = RotationOffset;
3579 m_lastVelocity = Velocity;
3580 m_lastAcceleration = Acceleration;
3581 m_lastAngularVelocity = AngularVelocity;
3582 m_lastUpdateSentTime = now;
3583 ClearUpdateSchedule();
3584 sendfull = true;
3585 break;
3586 } 3593 }
3587 } 3594
3588 if(sendterse) 3595 if((current & PrimUpdateFlags.TerseUpdate) != 0)
3589 {
3590 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3591 { 3596 {
3592 SendTerseUpdateToClient(client); 3597 m_lastPosition = AbsolutePosition;
3593 }); 3598 m_lastRotation = RotationOffset;
3599 m_lastVelocity = Velocity;
3600 m_lastAcceleration = Acceleration;
3601 m_lastAngularVelocity = AngularVelocity;
3602 m_lastUpdateSentTime = now;
3603 }
3604
3605 UpdateFlag = PrimUpdateFlags.None;
3594 } 3606 }
3595 else if(sendfull) 3607
3608 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3596 { 3609 {
3597 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3610 SendUpdateToClient(avatar.ControllingClient, current);
3598 { 3611 });
3599 SendFullUpdate(avatar.ControllingClient);
3600 });
3601 }
3602 } 3612 }
3603 3613
3604 /// <summary> 3614 /// <summary>
@@ -3608,10 +3618,10 @@ namespace OpenSim.Region.Framework.Scenes
3608 { 3618 {
3609 if (ParentGroup == null || ParentGroup.Scene == null) 3619 if (ParentGroup == null || ParentGroup.Scene == null)
3610 return; 3620 return;
3621
3611 lock(UpdateFlagLock) 3622 lock(UpdateFlagLock)
3612 { 3623 {
3613 if(UpdateFlag != UpdateRequired.NONE) 3624 UpdateFlag &= ~PrimUpdateFlags.TerseUpdate;
3614 return;
3615 3625
3616 // Update the "last" values 3626 // Update the "last" values
3617 m_lastPosition = AbsolutePosition; 3627 m_lastPosition = AbsolutePosition;
@@ -3635,8 +3645,7 @@ namespace OpenSim.Region.Framework.Scenes
3635 3645
3636 lock(UpdateFlagLock) 3646 lock(UpdateFlagLock)
3637 { 3647 {
3638 if(UpdateFlag != UpdateRequired.NONE) 3648 UpdateFlag &= ~PrimUpdateFlags.TerseUpdate;
3639 return;
3640 3649
3641 // Update the "last" values 3650 // Update the "last" values
3642 m_lastPosition = AbsolutePosition; 3651 m_lastPosition = AbsolutePosition;
@@ -3652,7 +3661,7 @@ namespace OpenSim.Region.Framework.Scenes
3652 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 3661 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3653 if (sp != null) 3662 if (sp != null)
3654 { 3663 {
3655 sp.SendAttachmentUpdate(this, UpdateRequired.TERSE); 3664 sp.SendAttachmentUpdate(this, PrimUpdateFlags.TerseUpdate);
3656 } 3665 }
3657 } 3666 }
3658 else 3667 else
@@ -3682,12 +3691,6 @@ namespace OpenSim.Region.Framework.Scenes
3682 public void SetBuoyancy(float fvalue) 3691 public void SetBuoyancy(float fvalue)
3683 { 3692 {
3684 Buoyancy = fvalue; 3693 Buoyancy = fvalue;
3685/*
3686 if (PhysActor != null)
3687 {
3688 PhysActor.Buoyancy = fvalue;
3689 }
3690 */
3691 } 3694 }
3692 3695
3693 public void SetDieAtEdge(bool p) 3696 public void SetDieAtEdge(bool p)
@@ -4085,7 +4088,8 @@ namespace OpenSim.Region.Framework.Scenes
4085 GroupID = groupID; 4088 GroupID = groupID;
4086// if (client != null) 4089// if (client != null)
4087// SendPropertiesToClient(client); 4090// SendPropertiesToClient(client);
4088 UpdateFlag = UpdateRequired.FULL; 4091 lock(UpdateFlagLock)
4092 UpdateFlag |= PrimUpdateFlags.FullUpdate;
4089 } 4093 }
4090 4094
4091 /// <summary> 4095 /// <summary>
@@ -4273,8 +4277,6 @@ namespace OpenSim.Region.Framework.Scenes
4273 Vector3 pos = GetWorldPosition(); 4277 Vector3 pos = GetWorldPosition();
4274 Quaternion rot = GetWorldRotation(); 4278 Quaternion rot = GetWorldRotation();
4275 4279
4276 // Variables prefixed with AX are Axiom.Math copies of the LL variety.
4277
4278 Quaternion AXrot = rot; 4280 Quaternion AXrot = rot;
4279 AXrot.Normalize(); 4281 AXrot.Normalize();
4280 4282
@@ -4645,7 +4647,7 @@ namespace OpenSim.Region.Framework.Scenes
4645 { 4647 {
4646 if (ParentGroup.RootPart.GetStatusSandbox()) 4648 if (ParentGroup.RootPart.GetStatusSandbox())
4647 { 4649 {
4648 if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10) 4650 if (Vector3.DistanceSquared(ParentGroup.RootPart.StatusSandboxPos, newPos) > 100)
4649 { 4651 {
4650 ParentGroup.RootPart.ScriptSetPhysicsStatus(false); 4652 ParentGroup.RootPart.ScriptSetPhysicsStatus(false);
4651 newPos = OffsetPosition; 4653 newPos = OffsetPosition;
@@ -5230,7 +5232,7 @@ namespace OpenSim.Region.Framework.Scenes
5230 // Materials capable viewers can send a ObjectImage packet 5232 // Materials capable viewers can send a ObjectImage packet
5231 // when nothing in TE has changed. MaterialID should be updated 5233 // when nothing in TE has changed. MaterialID should be updated
5232 // by the RenderMaterials CAP handler, so updating it here may cause a 5234 // by the RenderMaterials CAP handler, so updating it here may cause a
5233 // race condtion. Therefore, if no non-materials TE fields have changed, 5235 // race condtion. Therefore, if no non-materials TE fields have not changed,
5234 // we should ignore any changes and not update Shape.TextureEntry 5236 // we should ignore any changes and not update Shape.TextureEntry
5235 5237
5236 bool otherFieldsChanged = false; 5238 bool otherFieldsChanged = false;
@@ -5279,7 +5281,7 @@ namespace OpenSim.Region.Framework.Scenes
5279 } 5281 }
5280 5282
5281 if (changeFlags == 0) 5283 if (changeFlags == 0)
5282 return; 5284 return;
5283 m_shape.TextureEntry = newTex.GetBytes(); 5285 m_shape.TextureEntry = newTex.GetBytes();
5284 TriggerScriptChangedEvent(changeFlags); 5286 TriggerScriptChangedEvent(changeFlags);
5285 ParentGroup.HasGroupChanged = true; 5287 ParentGroup.HasGroupChanged = true;
@@ -5412,6 +5414,21 @@ namespace OpenSim.Region.Framework.Scenes
5412 5414
5413 #endregion Public Methods 5415 #endregion Public Methods
5414 5416
5417 public void SendUpdateToClient(IClientAPI remoteClient, PrimUpdateFlags PrimUpdateFlags)
5418 {
5419 if (ParentGroup.IsDeleted)
5420 return;
5421
5422 if (ParentGroup.IsAttachment &&
5423 (ParentGroup.RootPart != this || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint))
5424 return;
5425
5426 remoteClient.SendEntityUpdate(this, PrimUpdateFlags);
5427
5428 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
5429 }
5430
5431
5415 public void SendTerseUpdateToClient(IClientAPI remoteClient) 5432 public void SendTerseUpdateToClient(IClientAPI remoteClient)
5416 { 5433 {
5417 if (ParentGroup.IsDeleted) 5434 if (ParentGroup.IsDeleted)
@@ -5424,10 +5441,7 @@ namespace OpenSim.Region.Framework.Scenes
5424 5441
5425 // Causes this thread to dig into the Client Thread Data. 5442 // Causes this thread to dig into the Client Thread Data.
5426 // Remember your locking here! 5443 // Remember your locking here!
5427 remoteClient.SendEntityUpdate( 5444 remoteClient.SendEntityUpdate(this, PrimUpdateFlags.TerseUpdate);
5428 this,
5429 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5430 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
5431 5445
5432 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1); 5446 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
5433 } 5447 }
@@ -5691,5 +5705,75 @@ namespace OpenSim.Region.Framework.Scenes
5691 PhysActor.Building = true; 5705 PhysActor.Building = true;
5692 UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false); 5706 UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false);
5693 } 5707 }
5708
5709 private object animsLock = new object();
5710 public Dictionary<UUID, int> Animations = null;
5711 public Dictionary<UUID, string> AnimationsNames = null;
5712
5713 public bool AddAnimation(UUID animId, string animName)
5714 {
5715 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
5716 return false;
5717
5718 lock (animsLock)
5719 {
5720 if (Animations == null)
5721 Animations = new Dictionary<UUID, int>(1);
5722 if (AnimationsNames == null)
5723 AnimationsNames = new Dictionary<UUID, string>(1);
5724
5725 if (Animations.ContainsKey(animId))
5726 return false;
5727
5728 Animations[animId] = ParentGroup.Scene.NextObjectAnimationSequenceNumber;
5729 AnimationsNames[animId] = animName;
5730 ScheduleUpdate(PrimUpdateFlags.Animations);
5731 }
5732 return true;
5733 }
5734
5735 public bool RemoveAnimation(UUID animId)
5736 {
5737 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
5738 return false;
5739
5740 lock (animsLock)
5741 {
5742 if (Animations == null)
5743 return false;
5744
5745 if (Animations.ContainsKey(animId))
5746 {
5747 Animations.Remove(animId);
5748 if(AnimationsNames!=null)
5749 AnimationsNames.Remove(animId);
5750 ScheduleUpdate(PrimUpdateFlags.Animations);
5751 return true;
5752 }
5753 }
5754 return false;
5755 }
5756
5757 public int GetAnimations(out UUID[] ids, out int[] seqs)
5758 {
5759 ids = null;
5760 seqs = null;
5761
5762 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
5763 return -1;
5764
5765 lock (animsLock)
5766 {
5767 if (Animations == null)
5768 return -1;
5769 if(Animations.Count == 0)
5770 return 0;
5771 ids = new UUID[Animations.Count];
5772 Animations.Keys.CopyTo(ids, 0);
5773 seqs = new int[Animations.Count];
5774 Animations.Values.CopyTo(seqs, 0);
5775 return Animations.Count;
5776 }
5777 }
5694 } 5778 }
5695} 5779}