aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
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
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 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEventQueue.cs11
-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
6 files changed, 170 insertions, 335 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
index b525769..3f54ea5 100644
--- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
@@ -52,11 +52,12 @@ namespace OpenSim.Region.Framework.Interfaces
52 string capsURL, UUID avatarID, UUID sessionID, 52 string capsURL, UUID avatarID, UUID sessionID,
53 int regionSizeX, int regionSizeY); 53 int regionSizeX, int regionSizeY);
54 void ChatterboxInvitation(UUID sessionID, string sessionName, 54 void ChatterboxInvitation(UUID sessionID, string sessionName,
55 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, 55 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
56 uint timeStamp, bool offline, int parentEstateID, Vector3 position, 56 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
57 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); 57 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
58 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat, 58 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent,
59 bool isModerator, bool textMute, bool isEnterorLeave); 59 bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave);
60 void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason);
60 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); 61 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID);
61 void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data); 62 void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data);
62 OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono); 63 OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono);
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