aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorCharles Krinke2008-12-20 21:36:42 +0000
committerCharles Krinke2008-12-20 21:36:42 +0000
commit62dd67b8b8a7eb441d57f2b854444fbc5c4767d3 (patch)
treeb6c9f1123ae69ed2c6d67a4e939168b9140acb55
parentMantis#2881. Thank you kindly, SirKimba for a patch that: (diff)
downloadopensim-SC-62dd67b8b8a7eb441d57f2b854444fbc5c4767d3.zip
opensim-SC-62dd67b8b8a7eb441d57f2b854444fbc5c4767d3.tar.gz
opensim-SC-62dd67b8b8a7eb441d57f2b854444fbc5c4767d3.tar.bz2
opensim-SC-62dd67b8b8a7eb441d57f2b854444fbc5c4767d3.tar.xz
Mantis#2796. Thank you kindly, Gerhard for a patch that addresses:
On a call of llVolumeDetect(1) (or any other number !=0) volume detection is enabled. Together with VD, the phantom flag is set to the GUI. On a call of llVolumeDetect(0), vd detection is switched of again, also the phantom state is removed. On a call to llSetState(STATE_PHANTOM, false) while VD is active, also VD is switched off. The same is true for unchecking the phantom flag via GUI. This allows to take back VD without the need to script just by removing the phantom flag. Things missing in this patch: persistance of the volume-detection flag. This needs more discussion and will be included in another patch soon.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneGraph.cs4
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs34
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPart.cs96
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs7
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2
6 files changed, 139 insertions, 24 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneGraph.cs b/OpenSim/Region/Environment/Scenes/SceneGraph.cs
index b373c09..d261e2d 100644
--- a/OpenSim/Region/Environment/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneGraph.cs
@@ -1203,6 +1203,8 @@ namespace OpenSim.Region.Environment.Scenes
1203 /// <param name="localID"></param> 1203 /// <param name="localID"></param>
1204 /// <param name="packet"></param> 1204 /// <param name="packet"></param>
1205 /// <param name="remoteClient"></param> 1205 /// <param name="remoteClient"></param>
1206 /// This routine seems to get called when a user changes object settings in the viewer.
1207 /// If some one can confirm that, please change the comment according.
1206 protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient) 1208 protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient)
1207 { 1209 {
1208 SceneObjectGroup group = GetGroupByPrim(localID); 1210 SceneObjectGroup group = GetGroupByPrim(localID);
@@ -1210,7 +1212,7 @@ namespace OpenSim.Region.Environment.Scenes
1210 { 1212 {
1211 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1213 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1212 { 1214 {
1213 group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom); 1215 group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom, false); // VolumeDetect can't be set via UI and will always be off when a change is made there
1214 } 1216 }
1215 } 1217 }
1216 } 1218 }
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 5456282..f4ccc46 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -1431,21 +1431,45 @@ namespace OpenSim.Region.Environment.Scenes
1431 { 1431 {
1432 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); 1432 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1433 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); 1433 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1434 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom); 1434 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1435 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1435 } 1436 }
1436 1437
1437 public void ScriptSetTemporaryStatus(bool TemporaryStatus) 1438 public void ScriptSetTemporaryStatus(bool TemporaryStatus)
1438 { 1439 {
1439 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1440 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1440 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); 1441 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1441 UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom); 1442 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1443 UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect);
1442 } 1444 }
1443 1445
1444 public void ScriptSetPhantomStatus(bool PhantomStatus) 1446 public void ScriptSetPhantomStatus(bool PhantomStatus)
1445 { 1447 {
1446 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1448 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1447 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); 1449 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1448 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus); 1450 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1451 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect);
1452 }
1453
1454 public void ScriptSetVolumeDetect(bool VDStatus)
1455 {
1456 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1457 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1458 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1459 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus);
1460
1461 /*
1462 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
1463
1464 if (PhysActor != null) // Should always be the case now
1465 {
1466 PhysActor.SetVolumeDetect(param);
1467 }
1468 if (param != 0)
1469 AddFlag(PrimFlags.Phantom);
1470
1471 ScheduleFullUpdate();
1472 */
1449 } 1473 }
1450 1474
1451 public void applyImpulse(PhysicsVector impulse) 1475 public void applyImpulse(PhysicsVector impulse)
@@ -2251,7 +2275,7 @@ namespace OpenSim.Region.Environment.Scenes
2251 /// <param name="type"></param> 2275 /// <param name="type"></param>
2252 /// <param name="inUse"></param> 2276 /// <param name="inUse"></param>
2253 /// <param name="data"></param> 2277 /// <param name="data"></param>
2254 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom) 2278 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect)
2255 { 2279 {
2256 SceneObjectPart selectionPart = GetChildPart(localID); 2280 SceneObjectPart selectionPart = GetChildPart(localID);
2257 2281
@@ -2279,7 +2303,7 @@ namespace OpenSim.Region.Environment.Scenes
2279 2303
2280 foreach (SceneObjectPart part in m_parts.Values) 2304 foreach (SceneObjectPart part in m_parts.Values)
2281 { 2305 {
2282 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom); 2306 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2283 } 2307 }
2284 } 2308 }
2285 } 2309 }
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index 6b4d47a..0315c92 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -167,7 +167,11 @@ namespace OpenSim.Region.Environment.Scenes
167 167
168 [XmlIgnore] 168 [XmlIgnore]
169 public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f); 169 public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f);
170 170
171 [XmlIgnore]
172 public bool VolumeDetectActive = false; // XmlIgnore set to avoid problems with persistance until I come to care for this
173 // Certainly this must be a persistant setting finally
174
171 /// <summary> 175 /// <summary>
172 /// This part's inventory 176 /// This part's inventory
173 /// </summary> 177 /// </summary>
@@ -2178,6 +2182,16 @@ if (m_shape != null) {
2178 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics); 2182 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2179 } 2183 }
2180 2184
2185 public void ScriptSetVolumeDetect(bool SetVD)
2186 {
2187
2188 if (m_parentGroup != null)
2189 {
2190 m_parentGroup.ScriptSetVolumeDetect(SetVD);
2191 }
2192 }
2193
2194
2181 public void SculptTextureCallback(UUID textureID, AssetBase texture) 2195 public void SculptTextureCallback(UUID textureID, AssetBase texture)
2182 { 2196 {
2183 if (m_shape.SculptEntry) 2197 if (m_shape.SculptEntry)
@@ -2484,14 +2498,6 @@ if (m_shape != null) {
2484 } 2498 }
2485 } 2499 }
2486 2500
2487 public void SetVolumeDetect(int param)
2488 {
2489 if (PhysActor != null)
2490 {
2491 PhysActor.SetVolumeDetect(param);
2492 }
2493 }
2494
2495 public void SetGroup(UUID groupID, IClientAPI client) 2501 public void SetGroup(UUID groupID, IClientAPI client)
2496 { 2502 {
2497 _groupID = groupID; 2503 _groupID = groupID;
@@ -3184,17 +3190,46 @@ if (m_shape != null) {
3184 } 3190 }
3185 } 3191 }
3186 3192
3187 public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom) 3193 public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD)
3188 { 3194 {
3189 bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0); 3195 bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0);
3190 bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0); 3196 bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0);
3191 bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0); 3197 bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0);
3198 bool wasVD = VolumeDetectActive;
3192 3199
3193 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom)) 3200 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD) )
3194 { 3201 {
3195 return; 3202 return;
3196 } 3203 }
3197 3204
3205 // Special cases for VD. VD can only be called from a script
3206 // and can't be combined with changes to other states. So we can rely
3207 // that...
3208 // ... if VD is changed, all others are not.
3209 // ... if one of the others is changed, VD is not.
3210 if (IsVD) // VD is active, special logic applies
3211 {
3212 // State machine logic for VolumeDetect
3213 // More logic below
3214 bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom;
3215
3216 if (phanReset) // Phantom changes from on to off switch VD off too
3217 {
3218 IsVD = false; // Switch it of for the course of this routine
3219 VolumeDetectActive = false; // and also permanently
3220 if (PhysActor != null)
3221 PhysActor.SetVolumeDetect(0); // Let physics know about it too
3222 }
3223 else
3224 {
3225 IsPhantom = false;
3226 // If volumedetect is active we don't want phantom to be applied.
3227 // If this is a new call to VD out of the state "phantom"
3228 // this will also cause the prim to be visible to physics
3229 }
3230
3231 }
3232
3198 if (UsePhysics) 3233 if (UsePhysics)
3199 { 3234 {
3200 AddFlag(PrimFlags.Physics); 3235 AddFlag(PrimFlags.Physics);
@@ -3222,6 +3257,7 @@ if (m_shape != null) {
3222 } 3257 }
3223 } 3258 }
3224 3259
3260
3225 if (IsPhantom || IsAttachment) 3261 if (IsPhantom || IsAttachment)
3226 { 3262 {
3227 AddFlag(PrimFlags.Phantom); 3263 AddFlag(PrimFlags.Phantom);
@@ -3232,11 +3268,13 @@ if (m_shape != null) {
3232 PhysActor = null; 3268 PhysActor = null;
3233 } 3269 }
3234 } 3270 }
3235 else 3271 else // Not phantom
3236 { 3272 {
3237 RemFlag(PrimFlags.Phantom); 3273 RemFlag(PrimFlags.Phantom);
3274
3238 if (PhysActor == null) 3275 if (PhysActor == null)
3239 { 3276 {
3277 // It's not phantom anymore. So make sure the physics engine get's knowledge of it
3240 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 3278 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
3241 Name, 3279 Name,
3242 Shape, 3280 Shape,
@@ -3261,10 +3299,11 @@ if (m_shape != null) {
3261 } 3299 }
3262 } 3300 }
3263 } 3301 }
3264 else 3302 else // it already has a physical representation
3265 { 3303 {
3266 PhysActor.IsPhysical = UsePhysics; 3304 PhysActor.IsPhysical = UsePhysics;
3267 DoPhysicsPropertyUpdate(UsePhysics, false); 3305
3306 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
3268 if (m_parentGroup != null) 3307 if (m_parentGroup != null)
3269 { 3308 {
3270 if (!m_parentGroup.IsDeleted) 3309 if (!m_parentGroup.IsDeleted)
@@ -3278,6 +3317,32 @@ if (m_shape != null) {
3278 } 3317 }
3279 } 3318 }
3280 3319
3320 if (IsVD)
3321 {
3322 // If the above logic worked (this is urgent candidate to unit tests!)
3323 // we now have a physicsactor.
3324 // Defensive programming calls for a check here.
3325 // Better would be throwing an exception that could be catched by a unit test as the internal
3326 // logic should make sure, this Physactor is always here.
3327 if (this.PhysActor != null)
3328 {
3329 PhysActor.SetVolumeDetect(1);
3330 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
3331 this.VolumeDetectActive = true;
3332 }
3333
3334 }
3335 else
3336 { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
3337 // (mumbles, well, at least if you have infinte CPU powers :-) )
3338 if (this.PhysActor != null)
3339 {
3340 PhysActor.SetVolumeDetect(0);
3341 }
3342 this.VolumeDetectActive = false;
3343 }
3344
3345
3281 if (IsTemporary) 3346 if (IsTemporary)
3282 { 3347 {
3283 AddFlag(PrimFlags.TemporaryOnRez); 3348 AddFlag(PrimFlags.TemporaryOnRez);
@@ -3287,6 +3352,7 @@ if (m_shape != null) {
3287 RemFlag(PrimFlags.TemporaryOnRez); 3352 RemFlag(PrimFlags.TemporaryOnRez);
3288 } 3353 }
3289 // System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 3354 // System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
3355
3290 ParentGroup.HasGroupChanged = true; 3356 ParentGroup.HasGroupChanged = true;
3291 ScheduleFullUpdate(); 3357 ScheduleFullUpdate();
3292 } 3358 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 6f5abfa..b9c0936 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -127,6 +127,8 @@ namespace OpenSim.Region.Physics.OdePlugin
127 private bool m_isphysical = false; 127 private bool m_isphysical = false;
128 private bool m_isSelected = false; 128 private bool m_isSelected = false;
129 129
130 internal bool m_isVolumeDetect = false; // If true, this prim only detects collisions but doesn't collide actively
131
130 private bool m_throttleUpdates = false; 132 private bool m_throttleUpdates = false;
131 private int throttleCounter = 0; 133 private int throttleCounter = 0;
132 public int m_interpenetrationcount = 0; 134 public int m_interpenetrationcount = 0;
@@ -2226,7 +2228,10 @@ namespace OpenSim.Region.Physics.OdePlugin
2226 2228
2227 public override void SetVolumeDetect(int param) 2229 public override void SetVolumeDetect(int param)
2228 { 2230 {
2229 2231 lock (_parent_scene.OdeLock)
2232 {
2233 m_isVolumeDetect = (param!=0);
2234 }
2230 } 2235 }
2231 2236
2232 public override PhysicsVector CenterOfMass 2237 public override PhysicsVector CenterOfMass
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 7589750..c0b4b45 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -797,7 +797,25 @@ namespace OpenSim.Region.Physics.OdePlugin
797 797
798 #endregion 798 #endregion
799 799
800 if (contacts[i].depth >= 0f && !checkDupe(contacts[i], p2.PhysicsActorType)) 800 // Logic for collision handling
801 // Note, that if *all* contacts are skipped (VolumeDetect)
802 // The prim still detects (and forwards) collision events but
803 // appears to be phantom for the world
804 Boolean skipThisContact = false;
805
806 if (contacts[i].depth < 0f)
807 skipThisContact = true;
808
809 if (checkDupe(contacts[i], p2.PhysicsActorType))
810 skipThisContact = true;
811
812 if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect))
813 skipThisContact = true; // No collision on volume detect prims
814
815 if ((p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect))
816 skipThisContact = true; // No collision on volume detect prims
817
818 if (!skipThisContact)
801 { 819 {
802 // If we're colliding against terrain 820 // If we're colliding against terrain
803 if (name1 == "Terrain" || name2 == "Terrain") 821 if (name1 == "Terrain" || name2 == "Terrain")
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index b15189e..5ef9471 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -5736,7 +5736,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5736 { 5736 {
5737 if (!m_host.ParentGroup.IsDeleted) 5737 if (!m_host.ParentGroup.IsDeleted)
5738 { 5738 {
5739 m_host.ParentGroup.RootPart.SetVolumeDetect(detect); 5739 m_host.ParentGroup.RootPart.ScriptSetVolumeDetect(detect!=0);
5740 } 5740 }
5741 } 5741 }
5742 } 5742 }