aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
authorUbitUmarov2016-08-19 03:05:25 +0100
committerUbitUmarov2016-08-19 03:05:25 +0100
commit7ba3fb7b5d9c883b7a99d19f893ff6d43689b629 (patch)
tree1ea4937e30520d440979ab02e92882f6f54a3e73 /OpenSim/Region/Framework/Scenes
parentfix entity update flags update (diff)
parent catch some NULL refs (diff)
downloadopensim-SC-7ba3fb7b5d9c883b7a99d19f893ff6d43689b629.zip
opensim-SC-7ba3fb7b5d9c883b7a99d19f893ff6d43689b629.tar.gz
opensim-SC-7ba3fb7b5d9c883b7a99d19f893ff6d43689b629.tar.bz2
opensim-SC-7ba3fb7b5d9c883b7a99d19f893ff6d43689b629.tar.xz
merge issue
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs67
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs55
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs352
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs6
5 files changed, 164 insertions, 330 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index c913ec2..5669c43 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -108,6 +108,9 @@ namespace OpenSim.Region.Framework.Scenes
108 priority = GetPriorityByFrontBack(client, entity); 108 priority = GetPriorityByFrontBack(client, entity);
109 break; 109 break;
110*/ 110*/
111 case UpdatePrioritizationSchemes.SimpleAngularDistance:
112 priority = GetPriorityByAngularDistance(client, entity); // TODO: Reimplement SimpleAngularDistance
113 break;
111 case UpdatePrioritizationSchemes.BestAvatarResponsiveness: 114 case UpdatePrioritizationSchemes.BestAvatarResponsiveness:
112 default: 115 default:
113 priority = GetPriorityByBestAvatarResponsiveness(client, entity); 116 priority = GetPriorityByBestAvatarResponsiveness(client, entity);
@@ -241,7 +244,7 @@ namespace OpenSim.Region.Framework.Scenes
241*/ 244*/
242 if (distance > 10f) 245 if (distance > 10f)
243 { 246 {
244 float tmp = (float)Math.Log((double)distance) * 1.4426950408889634073599246810019f - 3.3219280948873623478703194294894f; 247 float tmp = (float)Math.Log((double)distance) * 1.442695f - 3.321928f;
245 // for a map identical to original: 248 // for a map identical to original:
246 // now 249 // now
247 // 1st constant is 1/(log(2)) (natural log) so we get log2(distance) 250 // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
@@ -269,5 +272,67 @@ namespace OpenSim.Region.Framework.Scenes
269 return pqueue; 272 return pqueue;
270 } 273 }
271 274
275 private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity)
276 {
277 uint pqueue = 2; // keep compiler happy
278
279 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
280 if (presence == null)
281 return PriorityQueue.NumberOfQueues - 1;
282
283 // All avatars other than our own go into pqueue 1
284 if (entity is ScenePresence)
285 return 1;
286
287 if (entity is SceneObjectPart)
288 {
289 // Attachments are high priority,
290 if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
291 return 2;
292
293 pqueue = ComputeAngleDistancePriority(presence, entity);
294
295 // Non physical prims are lower priority than physical prims
296 PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
297 if (physActor == null || !physActor.IsPhysical)
298 pqueue++;
299 }
300
301 return pqueue;
302 }
303
304 private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity)
305 {
306 double distance;
307
308 Vector3 presencePos = presence.AbsolutePosition;
309
310 SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
311 float bradius = group.GetBoundsRadius();
312 Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter();
313 distance = Vector3.Distance(presencePos, grppos);
314 distance -= bradius;
315 distance *= group.getAreaFactor();
316
317 // And convert the distance to a priority queue, this computation gives queues
318 // at 10, 20, 40, 80, 160, 320, 640, and 1280m
319 uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue
320 uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues;
321
322 if (distance > 10f)
323 {
324 float tmp = (float)Math.Log(distance) * 1.442695f - 3.321928f;
325 // for a map identical to original:
326 // now
327 // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
328 // 2st constant makes it be log2(distance/10)
329
330 pqueue += (uint)tmp;
331 if (pqueue > queues - 1)
332 pqueue = queues - 1;
333 }
334
335 return pqueue;
336 }
272 } 337 }
273} 338}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 33418e6..d5dbcaf 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3866,15 +3866,9 @@ namespace OpenSim.Region.Framework.Scenes
3866 foreach (uint localID in localIDs) 3866 foreach (uint localID in localIDs)
3867 { 3867 {
3868 SceneObjectPart part = GetSceneObjectPart(localID); 3868 SceneObjectPart part = GetSceneObjectPart(localID);
3869 if (part != null) // It is a prim 3869 if (part != null && part.ParentGroup != null &&
3870 { 3870 part.ParentGroup.RootPart == part)
3871 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid 3871 deleteIDs.Add(localID);
3872 {
3873 if (part.ParentGroup.RootPart != part) // Child part
3874 continue;
3875 }
3876 }
3877 deleteIDs.Add(localID);
3878 } 3872 }
3879 3873
3880 ForEachClient(c => c.SendKillObject(deleteIDs)); 3874 ForEachClient(c => c.SendKillObject(deleteIDs));
@@ -4458,7 +4452,7 @@ Label_GroupsDone:
4458 { 4452 {
4459 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4453 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
4460 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4454 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4461 reason = String.Format("Denied access to private region {0}: You are do not have access to that region.", 4455 reason = String.Format("Denied access to private region {0}: You do not have access to that region.",
4462 RegionInfo.RegionName); 4456 RegionInfo.RegionName);
4463 return false; 4457 return false;
4464 } 4458 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index efc1413..df6a1cf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1586,12 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes
1586 return m_boundsCenter; 1586 return m_boundsCenter;
1587 } 1587 }
1588 1588
1589 private float m_areaFactor;
1590 public float getAreaFactor()
1591 {
1592 // math is done in GetBoundsRadius();
1593 if(m_boundsRadius == null)
1594 GetBoundsRadius();
1595 return m_areaFactor;
1596 }
1597
1589 public float GetBoundsRadius() 1598 public float GetBoundsRadius()
1590 { 1599 {
1591 // this may need more threading work 1600 // this may need more threading work
1592 if(m_boundsRadius == null) 1601 if(m_boundsRadius == null)
1593 { 1602 {
1594 float res = 0; 1603 float res = 0;
1604 float areaF = 0;
1595 SceneObjectPart p; 1605 SceneObjectPart p;
1596 SceneObjectPart[] parts; 1606 SceneObjectPart[] parts;
1597 float partR; 1607 float partR;
@@ -1613,12 +1623,19 @@ namespace OpenSim.Region.Framework.Scenes
1613 } 1623 }
1614 if(partR > res) 1624 if(partR > res)
1615 res = partR; 1625 res = partR;
1626 if(p.maxSimpleArea() > areaF)
1627 areaF = p.maxSimpleArea();
1616 } 1628 }
1617 if(parts.Length > 1) 1629 if(parts.Length > 1)
1618 { 1630 {
1619 offset /= parts.Length; // basicly geometric center 1631 offset /= parts.Length; // basicly geometric center
1620 offset = offset * RootPart.RotationOffset; 1632 offset = offset * RootPart.RotationOffset;
1621 } 1633 }
1634
1635 areaF = 10.0f / areaF; // scale it
1636 areaF = Util.Clamp(areaF, 0.001f, 1000f); // clamp it
1637
1638 m_areaFactor = (float)Math.Sqrt(areaF);
1622 m_boundsCenter = offset; 1639 m_boundsCenter = offset;
1623 m_boundsRadius = res; 1640 m_boundsRadius = res;
1624 return res; 1641 return res;
@@ -2048,41 +2065,37 @@ namespace OpenSim.Region.Framework.Scenes
2048 { 2065 {
2049 // We need to keep track of this state in case this group is still queued for backup. 2066 // We need to keep track of this state in case this group is still queued for backup.
2050 IsDeleted = true; 2067 IsDeleted = true;
2051 HasGroupChanged = true;
2052 2068
2053 DetachFromBackup(); 2069 DetachFromBackup();
2054 2070
2071 if(Scene == null) // should not happen unless restart/shutdown ?
2072 return;
2073
2055 SceneObjectPart[] parts = m_parts.GetArray(); 2074 SceneObjectPart[] parts = m_parts.GetArray();
2056 for (int i = 0; i < parts.Length; i++) 2075 for (int i = 0; i < parts.Length; i++)
2057 { 2076 {
2058 SceneObjectPart part = parts[i]; 2077 SceneObjectPart part = parts[i];
2059 2078
2060 if (Scene != null) 2079 Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2061 { 2080 {
2062 Scene.ForEachScenePresence(delegate(ScenePresence avatar) 2081 if (!avatar.IsChildAgent && avatar.ParentID == LocalId)
2063 { 2082 avatar.StandUp();
2064 if (!avatar.IsChildAgent && avatar.ParentID == LocalId)
2065 avatar.StandUp();
2066 2083
2067 if (!silent) 2084 if (!silent)
2085 {
2086 part.ClearUpdateSchedule();
2087 if (part == m_rootPart)
2068 { 2088 {
2069 part.ClearUpdateSchedule(); 2089 if (!IsAttachment
2070 if (part == m_rootPart) 2090 || AttachedAvatar == avatar.ControllingClient.AgentId
2091 || !HasPrivateAttachmentPoint)
2071 { 2092 {
2072 if (!IsAttachment 2093 // Send a kill object immediately
2073 || AttachedAvatar == avatar.ControllingClient.AgentId 2094 avatar.ControllingClient.SendKillObject(new List<uint> { part.LocalId });
2074 || !HasPrivateAttachmentPoint)
2075 {
2076 // Send a kill object immediately
2077 avatar.ControllingClient.SendKillObject(new List<uint> { part.LocalId });
2078 // Also, send a terse update; in case race conditions make the object pop again in the client,
2079 // this update will send another kill object
2080 m_rootPart.SendTerseUpdateToClient(avatar.ControllingClient);
2081 }
2082 } 2095 }
2083 } 2096 }
2084 }); 2097 }
2085 } 2098 });
2086 } 2099 }
2087 } 2100 }
2088 2101
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 0847b0b..01a323e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -285,7 +285,23 @@ namespace OpenSim.Region.Framework.Scenes
285 // but reversed logic: bit cleared means free to rotate 285 // but reversed logic: bit cleared means free to rotate
286 public byte RotationAxisLocks = 0; 286 public byte RotationAxisLocks = 0;
287 287
288 public bool VolumeDetectActive; 288 // WRONG flag in libOmvPrimFlags
289 private const uint primFlagVolumeDetect = (uint)PrimFlags.JointLP2P;
290
291 public bool VolumeDetectActive
292 {
293 get
294 {
295 return (Flags & (PrimFlags)primFlagVolumeDetect) != 0;
296 }
297 set
298 {
299 if(value)
300 Flags |= (PrimFlags)primFlagVolumeDetect;
301 else
302 Flags &= (PrimFlags)(~primFlagVolumeDetect);
303 }
304 }
289 305
290 public bool IsWaitingForFirstSpinUpdatePacket; 306 public bool IsWaitingForFirstSpinUpdatePacket;
291 307
@@ -1188,6 +1204,33 @@ namespace OpenSim.Region.Framework.Scenes
1188 } 1204 }
1189 } 1205 }
1190 1206
1207 public float maxSimpleArea()
1208 {
1209 float a,b;
1210 float sx = m_shape.Scale.X;
1211 float sy = m_shape.Scale.Y;
1212 float sz = m_shape.Scale.Z;
1213
1214 if( sx > sy)
1215 {
1216 a = sx;
1217 if(sy > sz)
1218 b = sy;
1219 else
1220 b = sz;
1221 }
1222 else
1223 {
1224 a = sy;
1225 if(sx > sz)
1226 b = sx;
1227 else
1228 b = sz;
1229 }
1230
1231 return a * b;
1232 }
1233
1191 public UpdateRequired UpdateFlag { get; set; } 1234 public UpdateRequired UpdateFlag { get; set; }
1192 public bool UpdatePhysRequired { get; set; } 1235 public bool UpdatePhysRequired { get; set; }
1193 1236
@@ -2078,12 +2121,6 @@ namespace OpenSim.Region.Framework.Scenes
2078 2121
2079 if (localGlobalTF) 2122 if (localGlobalTF)
2080 { 2123 {
2081/*
2082 Quaternion grot = GetWorldRotation();
2083 Quaternion AXgrot = grot;
2084 Vector3 AXimpulsei = impulsei;
2085 Vector3 newimpulse = AXimpulsei * AXgrot;
2086 */
2087 torque *= GetWorldRotation(); 2124 torque *= GetWorldRotation();
2088 } 2125 }
2089 2126
@@ -2222,16 +2259,8 @@ namespace OpenSim.Region.Framework.Scenes
2222 2259
2223 if (userExposed) 2260 if (userExposed)
2224 { 2261 {
2225/*
2226 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
2227 {
2228 ParentGroup.Scene.AssetService.Get(
2229 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
2230 }
2231*/
2232 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2262 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
2233 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2263 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2234// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
2235 } 2264 }
2236 2265
2237 if (dupe.PhysActor != null) 2266 if (dupe.PhysActor != null)
@@ -2245,23 +2274,6 @@ namespace OpenSim.Region.Framework.Scenes
2245 } 2274 }
2246 2275
2247 /// <summary> 2276 /// <summary>
2248 /// Called back by asynchronous asset fetch.
2249 /// </summary>
2250 /// <param name="id">ID of asset received</param>
2251 /// <param name="sender">Register</param>
2252 /// <param name="asset"></param>
2253/*
2254 protected void AssetReceived(string id, Object sender, AssetBase asset)
2255 {
2256 if (asset != null)
2257 SculptTextureCallback(asset);
2258// else
2259// m_log.WarnFormat(
2260// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
2261// Name, UUID, id);
2262 }
2263*/
2264 /// <summary>
2265 /// Do a physics property update for a NINJA joint. 2277 /// Do a physics property update for a NINJA joint.
2266 /// </summary> 2278 /// </summary>
2267 /// <param name="UsePhysics"></param> 2279 /// <param name="UsePhysics"></param>
@@ -3243,39 +3255,6 @@ namespace OpenSim.Region.Framework.Scenes
3243 } 3255 }
3244 3256
3245 /// <summary> 3257 /// <summary>
3246 /// Set sculpt and mesh data, and tell the physics engine to process the change.
3247 /// </summary>
3248 /// <param name="texture">The mesh itself.</param>
3249/*
3250 public void SculptTextureCallback(AssetBase texture)
3251 {
3252 if (m_shape.SculptEntry)
3253 {
3254 // commented out for sculpt map caching test - null could mean a cached sculpt map has been found
3255 //if (texture != null)
3256 {
3257 if (texture != null)
3258 {
3259// m_log.DebugFormat(
3260// "[SCENE OBJECT PART]: Setting sculpt data for {0} on SculptTextureCallback()", Name);
3261
3262 m_shape.SculptData = texture.Data;
3263 }
3264
3265 PhysicsActor pa = PhysActor;
3266
3267 if (pa != null)
3268 {
3269 // Update the physics actor with the new loaded sculpt data and set the taint signal.
3270 pa.Shape = m_shape;
3271
3272 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
3273 }
3274 }
3275 }
3276 }
3277*/
3278 /// <summary>
3279 /// Send a full update to the client for the given part 3258 /// Send a full update to the client for the given part
3280 /// </summary> 3259 /// </summary>
3281 /// <param name="remoteClient"></param> 3260 /// <param name="remoteClient"></param>
@@ -4015,103 +3994,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4015 } 3994 }
4016 } 3995 }
4017 3996
4018 public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot)
4019 {
4020 // In this case we're using a sphere with a radius of the largest dimension of the prim
4021 // TODO: Change to take shape into account
4022
4023 EntityIntersection result = new EntityIntersection();
4024 Vector3 vAbsolutePosition = AbsolutePosition;
4025 Vector3 vScale = Scale;
4026 Vector3 rOrigin = iray.Origin;
4027 Vector3 rDirection = iray.Direction;
4028
4029 //rDirection = rDirection.Normalize();
4030 // Buidling the first part of the Quadratic equation
4031 Vector3 r2ndDirection = rDirection*rDirection;
4032 float itestPart1 = r2ndDirection.X + r2ndDirection.Y + r2ndDirection.Z;
4033
4034 // Buidling the second part of the Quadratic equation
4035 Vector3 tmVal2 = rOrigin - vAbsolutePosition;
4036 Vector3 r2Direction = rDirection*2.0f;
4037 Vector3 tmVal3 = r2Direction*tmVal2;
4038
4039 float itestPart2 = tmVal3.X + tmVal3.Y + tmVal3.Z;
4040
4041 // Buidling the third part of the Quadratic equation
4042 Vector3 tmVal4 = rOrigin*rOrigin;
4043 Vector3 tmVal5 = vAbsolutePosition*vAbsolutePosition;
4044
4045 Vector3 tmVal6 = vAbsolutePosition*rOrigin;
4046
4047 // Set Radius to the largest dimension of the prim
4048 float radius = 0f;
4049 if (vScale.X > radius)
4050 radius = vScale.X;
4051 if (vScale.Y > radius)
4052 radius = vScale.Y;
4053 if (vScale.Z > radius)
4054 radius = vScale.Z;
4055
4056 // the second part of this is the default prim size
4057 // once we factor in the aabb of the prim we're adding we can
4058 // change this to;
4059 // radius = (radius / 2) - 0.01f;
4060 //
4061 radius = (radius / 2) + (0.5f / 2) - 0.1f;
4062
4063 //radius = radius;
4064
4065 float itestPart3 = tmVal4.X + tmVal4.Y + tmVal4.Z + tmVal5.X + tmVal5.Y + tmVal5.Z -
4066 (2.0f*(tmVal6.X + tmVal6.Y + tmVal6.Z + (radius*radius)));
4067
4068 // Yuk Quadradrics.. Solve first
4069 float rootsqr = (itestPart2*itestPart2) - (4.0f*itestPart1*itestPart3);
4070 if (rootsqr < 0.0f)
4071 {
4072 // No intersection
4073 return result;
4074 }
4075 float root = ((-itestPart2) - (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f);
4076
4077 if (root < 0.0f)
4078 {
4079 // perform second quadratic root solution
4080 root = ((-itestPart2) + (float) Math.Sqrt((double) rootsqr))/(itestPart1*2.0f);
4081
4082 // is there any intersection?
4083 if (root < 0.0f)
4084 {
4085 // nope, no intersection
4086 return result;
4087 }
4088 }
4089
4090 // We got an intersection. putting together an EntityIntersection object with the
4091 // intersection information
4092 Vector3 ipoint =
4093 new Vector3(iray.Origin.X + (iray.Direction.X*root), iray.Origin.Y + (iray.Direction.Y*root),
4094 iray.Origin.Z + (iray.Direction.Z*root));
4095
4096 result.HitTF = true;
4097 result.ipoint = ipoint;
4098
4099 // Normal is calculated by the difference and then normalizing the result
4100 Vector3 normalpart = ipoint - vAbsolutePosition;
4101 result.normal = normalpart / normalpart.Length();
4102
4103 // It's funny how the Vector3 object has a Distance function, but the Axiom.Math object doesn't.
4104 // I can write a function to do it.. but I like the fact that this one is Static.
4105
4106 Vector3 distanceConvert1 = new Vector3(iray.Origin.X, iray.Origin.Y, iray.Origin.Z);
4107 Vector3 distanceConvert2 = new Vector3(ipoint.X, ipoint.Y, ipoint.Z);
4108 float distance = (float) Util.GetDistanceTo(distanceConvert1, distanceConvert2);
4109
4110 result.distance = distance;
4111
4112 return result;
4113 }
4114
4115 public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly, bool faceCenters) 3997 public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly, bool faceCenters)
4116 { 3998 {
4117 // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes 3999 // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes
@@ -4479,15 +4361,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4479 public void UpdateExtraParam(ushort type, bool inUse, byte[] data) 4361 public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
4480 { 4362 {
4481 m_shape.ReadInUpdateExtraParam(type, inUse, data); 4363 m_shape.ReadInUpdateExtraParam(type, inUse, data);
4482/* 4364
4483 if (type == 0x30)
4484 {
4485 if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero)
4486 {
4487 ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived);
4488 }
4489 }
4490*/
4491 if (ParentGroup != null) 4365 if (ParentGroup != null)
4492 { 4366 {
4493 ParentGroup.HasGroupChanged = true; 4367 ParentGroup.HasGroupChanged = true;
@@ -4714,9 +4588,11 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4714 4588
4715 VolumeDetectActive = SetVD; 4589 VolumeDetectActive = SetVD;
4716 4590
4717 // volume detector implies phantom 4591 // volume detector implies phantom we need to decouple this mess
4718 if (VolumeDetectActive) 4592 if (SetVD)
4719 SetPhantom = true; 4593 SetPhantom = true;
4594 else if(wasVD)
4595 SetPhantom = false;
4720 4596
4721 if (UsePhysics) 4597 if (UsePhysics)
4722 AddFlag(PrimFlags.Physics); 4598 AddFlag(PrimFlags.Physics);
@@ -4733,7 +4609,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4733 else 4609 else
4734 RemFlag(PrimFlags.TemporaryOnRez); 4610 RemFlag(PrimFlags.TemporaryOnRez);
4735 4611
4736
4737 if (ParentGroup.Scene == null) 4612 if (ParentGroup.Scene == null)
4738 return; 4613 return;
4739 4614
@@ -4763,26 +4638,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4763 { 4638 {
4764 AddToPhysics(UsePhysics, SetPhantom, building, false); 4639 AddToPhysics(UsePhysics, SetPhantom, building, false);
4765 pa = PhysActor; 4640 pa = PhysActor;
4766/* 4641
4767 if (pa != null)
4768 {
4769 if (
4770// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4771// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4772// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4773// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4774// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4775// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4776 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4777 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4778 (CollisionSound != UUID.Zero)
4779 )
4780 {
4781 pa.OnCollisionUpdate += PhysicsCollision;
4782 pa.SubscribeEvents(1000);
4783 }
4784 }
4785*/
4786 if (pa != null) 4642 if (pa != null)
4787 { 4643 {
4788 pa.SetMaterial(Material); 4644 pa.SetMaterial(Material);
@@ -4793,12 +4649,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4793 { 4649 {
4794 4650
4795 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. 4651 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4796/* moved into DoPhysicsPropertyUpdate
4797 if(VolumeDetectActive)
4798 pa.SetVolumeDetect(1);
4799 else
4800 pa.SetVolumeDetect(0);
4801*/
4802 4652
4803 if (pa.Building != building) 4653 if (pa.Building != building)
4804 pa.Building = building; 4654 pa.Building = building;
@@ -4807,32 +4657,8 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4807 UpdatePhysicsSubscribedEvents(); 4657 UpdatePhysicsSubscribedEvents();
4808 } 4658 }
4809 } 4659 }
4810 if (SetVD)
4811 {
4812 // If the above logic worked (this is urgent candidate to unit tests!)
4813 // we now have a physicsactor.
4814 // Defensive programming calls for a check here.
4815 // Better would be throwing an exception that could be catched by a unit test as the internal
4816 // logic should make sure, this Physactor is always here.
4817 if (pa != null)
4818 {
4819 pa.SetVolumeDetect(1);
4820 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4821 VolumeDetectActive = true;
4822 }
4823 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4824 }
4825 else if (SetVD != wasVD)
4826 {
4827 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4828 // (mumbles, well, at least if you have infinte CPU powers :-))
4829 if (pa != null)
4830 pa.SetVolumeDetect(0);
4831 4660
4832 RemFlag(PrimFlags.Phantom); 4661 // and last in case we have a new actor and not building
4833 VolumeDetectActive = false;
4834 }
4835 // and last in case we have a new actor and not building
4836 4662
4837 if (ParentGroup != null) 4663 if (ParentGroup != null)
4838 { 4664 {
@@ -5094,42 +4920,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
5094 } 4920 }
5095 4921
5096 /// <summary> 4922 /// <summary>
5097 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
5098 /// engine can use it.
5099 /// </summary>
5100 /// <remarks>
5101 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
5102 /// </remarks>
5103/*
5104 public void CheckSculptAndLoad()
5105 {
5106// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
5107
5108 return;
5109
5110 if (ParentGroup.IsDeleted)
5111 return;
5112
5113 if ((ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
5114 return;
5115
5116 if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero)
5117 {
5118 // check if a previously decoded sculpt map has been cached
5119 // We don't read the file here - the meshmerizer will do that later.
5120 // TODO: Could we simplify the meshmerizer code by reading and setting the data here?
5121 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString())))
5122 {
5123 SculptTextureCallback(null);
5124 }
5125 else
5126 {
5127 ParentGroup.Scene.AssetService.Get(Shape.SculptTexture.ToString(), this, AssetReceived);
5128 }
5129 }
5130 }
5131*/
5132 /// <summary>
5133 /// Update the texture entry for this part. 4923 /// Update the texture entry for this part.
5134 /// </summary> 4924 /// </summary>
5135 /// <param name="serializedTextureEntry"></param> 4925 /// <param name="serializedTextureEntry"></param>
@@ -5259,7 +5049,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
5259 { 5049 {
5260 // subscribe to physics updates. 5050 // subscribe to physics updates.
5261 pa.OnCollisionUpdate += PhysicsCollision; 5051 pa.OnCollisionUpdate += PhysicsCollision;
5262 pa.SubscribeEvents(100); // 10 reports per second 5052 pa.SubscribeEvents(50); // 20 reports per second
5263 } 5053 }
5264 else 5054 else
5265 { 5055 {
@@ -5304,41 +5094,8 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
5304 { 5094 {
5305 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5095 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
5306 } 5096 }
5307/*
5308 PhysicsActor pa = PhysActor;
5309 if (pa != null)
5310 {
5311 if (
5312// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5313// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5314// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5315// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5316// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5317// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5318 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5319 )
5320 {
5321 // subscribe to physics updates.
5322 pa.OnCollisionUpdate += PhysicsCollision;
5323 pa.SubscribeEvents(1000);
5324 }
5325 else
5326 {
5327 pa.UnSubscribeEvents();
5328 pa.OnCollisionUpdate -= PhysicsCollision;
5329 }
5330 }
5331 */
5332 UpdatePhysicsSubscribedEvents();
5333 5097
5334 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5098 UpdatePhysicsSubscribedEvents();
5335 //{
5336 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
5337 //}
5338 //else
5339 //{
5340 // ParentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
5341 //}
5342 5099
5343 LocalFlags = (PrimFlags)objectflagupdate; 5100 LocalFlags = (PrimFlags)objectflagupdate;
5344 5101
@@ -5393,6 +5150,9 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
5393 5150
5394 public void SendTerseUpdateToClient(IClientAPI remoteClient) 5151 public void SendTerseUpdateToClient(IClientAPI remoteClient)
5395 { 5152 {
5153 if (ParentGroup.IsDeleted)
5154 return;
5155
5396 if (ParentGroup.IsAttachment 5156 if (ParentGroup.IsAttachment
5397 && (ParentGroup.RootPart != this 5157 && (ParentGroup.RootPart != this
5398 || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint)) 5158 || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint))
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 1737e3c..e98e631 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -107,7 +107,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
107 m_so1.ScriptSetVolumeDetect(true); 107 m_so1.ScriptSetVolumeDetect(true);
108 108
109// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); 109// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
110 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); 110 // PrimFlags.JointLP2P is incorrect it now means VolumeDetect (as defined by viewers)
111 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.JointLP2P));
111 112
112 m_so1.ScriptSetVolumeDetect(false); 113 m_so1.ScriptSetVolumeDetect(false);
113 114
@@ -146,7 +147,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
146 m_so1.ScriptSetPhysicsStatus(true); 147 m_so1.ScriptSetPhysicsStatus(true);
147 m_so1.ScriptSetVolumeDetect(true); 148 m_so1.ScriptSetVolumeDetect(true);
148 149
149 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.Physics)); 150 // PrimFlags.JointLP2P is incorrect it now means VolumeDetect (as defined by viewers)
151 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.Physics | PrimFlags.JointLP2P));
150 152
151 m_so1.ScriptSetVolumeDetect(false); 153 m_so1.ScriptSetVolumeDetect(false);
152 154