aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs283
1 files changed, 145 insertions, 138 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index f70b259..a17862e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1577,16 +1577,12 @@ namespace OpenSim.Region.Framework.Scenes
1577 /// </summary> 1577 /// </summary>
1578 /// <param name="rootObjectFlags"></param> 1578 /// <param name="rootObjectFlags"></param>
1579 /// <param name="VolumeDetectActive"></param> 1579 /// <param name="VolumeDetectActive"></param>
1580// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1580
1581 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building) 1581 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
1582 { 1582 {
1583 if (!ParentGroup.Scene.CollidablePrims) 1583 if (!ParentGroup.Scene.CollidablePrims)
1584 return; 1584 return;
1585 1585
1586// m_log.DebugFormat(
1587// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}",
1588// Name, LocalId, UUID, m_physicalPrim);
1589
1590 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1586 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0;
1591 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1587 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0;
1592 1588
@@ -1597,15 +1593,16 @@ namespace OpenSim.Region.Framework.Scenes
1597 else 1593 else
1598 { 1594 {
1599 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1595 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored
1600 if (VolumeDetectActive) 1596// if (VolumeDetectActive)
1601 isPhantom = false; 1597// isPhantom = false;
1602 1598
1603 // Added clarification.. since A rigid body is an object that you can kick around, etc. 1599 // Added clarification.. since A rigid body is an object that you can kick around, etc.
1604 bool RigidBody = isPhysical && !isPhantom; 1600// bool RigidBody = isPhysical && !isPhantom;
1605 1601
1606 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1602 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
1607 // or flexible 1603 // or flexible
1608 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 1604 // if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1605 if ((!isPhantom || isPhysical || VolumeDetectActive) && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1609 { 1606 {
1610 Vector3 velocity = Velocity; 1607 Vector3 velocity = Velocity;
1611 Vector3 rotationalVelocity = AngularVelocity; 1608 Vector3 rotationalVelocity = AngularVelocity;
@@ -1616,9 +1613,9 @@ namespace OpenSim.Region.Framework.Scenes
1616 Shape, 1613 Shape,
1617 AbsolutePosition, 1614 AbsolutePosition,
1618 Scale, 1615 Scale,
1619// RotationOffset, 1616 GetWorldRotation(),
1620 GetWorldRotation(), // physics wants world rotation 1617 isPhysical,
1621 RigidBody, 1618 isPhantom,
1622 m_localId); 1619 m_localId);
1623 } 1620 }
1624 catch 1621 catch
@@ -1637,8 +1634,9 @@ namespace OpenSim.Region.Framework.Scenes
1637 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId) 1634 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
1638 m_vehicle.SetVehicle(PhysActor); 1635 m_vehicle.SetVehicle(PhysActor);
1639 1636
1640 DoPhysicsPropertyUpdate(RigidBody, true); 1637 DoPhysicsPropertyUpdate(isPhysical, true);
1641 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1638 if(VolumeDetectActive) // change if not the default only
1639 PhysActor.SetVolumeDetect(1);
1642 1640
1643 if (!building) 1641 if (!building)
1644 PhysActor.Building = false; 1642 PhysActor.Building = false;
@@ -1888,73 +1886,62 @@ namespace OpenSim.Region.Framework.Scenes
1888 { 1886 {
1889 if (UsePhysics != PhysActor.IsPhysical || isNew) 1887 if (UsePhysics != PhysActor.IsPhysical || isNew)
1890 { 1888 {
1891 if (PhysActor.IsPhysical) // implies UsePhysics==false for this block 1889 if (PhysActor.IsPhysical)
1892 { 1890 {
1893 if (!isNew) 1891 if (!isNew) // implies UsePhysics==false for this block
1892 {
1894 ParentGroup.Scene.RemovePhysicalPrim(1); 1893 ParentGroup.Scene.RemovePhysicalPrim(1);
1895 1894
1896 Velocity = new Vector3(0, 0, 0); 1895 Velocity = new Vector3(0, 0, 0);
1897 Acceleration = new Vector3(0, 0, 0); 1896 Acceleration = new Vector3(0, 0, 0);
1898 if (ParentGroup.RootPart == this) 1897 if (ParentGroup.RootPart == this)
1899 AngularVelocity = new Vector3(0, 0, 0); 1898 AngularVelocity = new Vector3(0, 0, 0);
1900 1899
1901 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 1900 if (PhysActor.Phantom)
1902 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; 1901 {
1903 PhysActor.delink(); 1902 RemoveFromPhysics();
1903 return;
1904 }
1904 1905
1905 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 1906 PhysActor.IsPhysical = UsePhysics;
1906 { 1907 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1907 // destroy all joints connected to this now deactivated body 1908 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
1908 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); 1909 PhysActor.delink();
1910 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
1911 {
1912 // destroy all joints connected to this now deactivated body
1913 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor);
1914 }
1909 } 1915 }
1910
1911 // stop client-side interpolation of all joint proxy objects that have just been deleted
1912 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback,
1913 // which stops client-side interpolation of deactivated joint proxy objects.
1914 }
1915
1916 if (!UsePhysics && !isNew)
1917 {
1918 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1919 // prim still has velocity and continues to interpolate its position along the old
1920 // velocity-vector.
1921 Velocity = new Vector3(0, 0, 0);
1922 Acceleration = new Vector3(0, 0, 0);
1923 if (ParentGroup.RootPart == this)
1924 AngularVelocity = new Vector3(0, 0, 0);
1925 //RotationalVelocity = new Vector3(0, 0, 0);
1926 } 1916 }
1927 1917
1928 PhysActor.IsPhysical = UsePhysics; 1918 if (PhysActor.IsPhysical != UsePhysics)
1929 1919 PhysActor.IsPhysical = UsePhysics;
1930 // If we're not what we're supposed to be in the physics scene, recreate ourselves.
1931 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
1932 /// that's not wholesome. Had to make Scene public
1933 //PhysActor = null;
1934 1920
1935 if ((Flags & PrimFlags.Phantom) == 0) 1921 if (UsePhysics)
1936 { 1922 {
1937 if (UsePhysics) 1923 if (ParentGroup.RootPart.KeyframeMotion != null)
1938 { 1924 ParentGroup.RootPart.KeyframeMotion.Stop();
1939 if (ParentGroup.RootPart.KeyframeMotion != null) 1925 ParentGroup.RootPart.KeyframeMotion = null;
1940 ParentGroup.RootPart.KeyframeMotion.Stop(); 1926 ParentGroup.Scene.AddPhysicalPrim(1);
1941 ParentGroup.RootPart.KeyframeMotion = null;
1942 ParentGroup.Scene.AddPhysicalPrim(1);
1943 1927
1944 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 1928 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1945 PhysActor.OnOutOfBounds += PhysicsOutOfBounds; 1929 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1946 1930
1947 if (ParentID != 0 && ParentID != LocalId) 1931 if (ParentID != 0 && ParentID != LocalId)
1932 {
1933 if (ParentGroup.RootPart.PhysActor != null)
1948 { 1934 {
1949 if (ParentGroup.RootPart.PhysActor != null) 1935 PhysActor.link(ParentGroup.RootPart.PhysActor);
1950 {
1951 PhysActor.link(ParentGroup.RootPart.PhysActor);
1952 }
1953 } 1936 }
1954 } 1937 }
1955 } 1938 }
1956 } 1939 }
1957 1940
1941 bool phan = ((Flags & PrimFlags.Phantom) != 0);
1942 if (PhysActor.Phantom != phan)
1943 PhysActor.Phantom = phan;
1944
1958 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 1945 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1959 // mesh data. 1946 // mesh data.
1960 if (Shape.SculptEntry) 1947 if (Shape.SculptEntry)
@@ -4355,40 +4342,45 @@ namespace OpenSim.Region.Framework.Scenes
4355 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); 4342 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
4356 bool wasVD = VolumeDetectActive; 4343 bool wasVD = VolumeDetectActive;
4357 4344
4358// m_log.DebugFormat("[SOP]: Old states: phys: {0} temp: {1} phan: {2} vd: {3}", wasUsingPhysics, wasTemporary, wasPhantom, wasVD);
4359// m_log.DebugFormat("[SOP]: New states: phys: {0} temp: {1} phan: {2} vd: {3}", UsePhysics, SetTemporary, SetPhantom, SetVD);
4360
4361 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4345 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4362 return; 4346 return;
4363 4347
4348 // do this first
4349 if (building && PhysActor != null && PhysActor.Building != building)
4350 PhysActor.Building = building;
4351
4364 // Special cases for VD. VD can only be called from a script 4352 // Special cases for VD. VD can only be called from a script
4365 // and can't be combined with changes to other states. So we can rely 4353 // and can't be combined with changes to other states. So we can rely
4366 // that... 4354 // that...
4367 // ... if VD is changed, all others are not. 4355 // ... if VD is changed, all others are not.
4368 // ... if one of the others is changed, VD is not. 4356 // ... if one of the others is changed, VD is not.
4369 // do this first 4357
4370 if (building && PhysActor != null && PhysActor.Building != building)
4371 PhysActor.Building = building;
4372 if (SetVD) // VD is active, special logic applies 4358 if (SetVD) // VD is active, special logic applies
4373 {
4374 // State machine logic for VolumeDetect
4375 // More logic below
4376 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4377 4359
4378 if (phanReset) // Phantom changes from on to off switch VD off too 4360 /* volume detection is now independent of phantom in sl
4379 { 4361
4380 SetVD = false; // Switch it of for the course of this routine 4362 {
4381 VolumeDetectActive = false; // and also permanently 4363 // State machine logic for VolumeDetect
4382 if (PhysActor != null) 4364 // More logic below
4383 PhysActor.SetVolumeDetect(0); // Let physics know about it too 4365
4384 } 4366
4385 else 4367 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4386 { 4368
4387 // If volumedetect is active we don't want phantom to be applied. 4369 if (phanReset) // Phantom changes from on to off switch VD off too
4388 // If this is a new call to VD out of the state "phantom" 4370 {
4389 // this will also cause the prim to be visible to physics 4371 SetVD = false; // Switch it of for the course of this routine
4372 VolumeDetectActive = false; // and also permanently
4373 if (PhysActor != null)
4374 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4375 }
4376 else
4377 {
4378 // If volumedetect is active we don't want phantom to be applied.
4379 // If this is a new call to VD out of the state "phantom"
4380 // this will also cause the prim to be visible to physics
4381 */
4390 SetPhantom = false; 4382 SetPhantom = false;
4391 } 4383/* }
4392 } 4384 }
4393 else if (wasVD) 4385 else if (wasVD)
4394 { 4386 {
@@ -4400,10 +4392,11 @@ namespace OpenSim.Region.Framework.Scenes
4400 { 4392 {
4401 SetPhantom = true; 4393 SetPhantom = true;
4402 } 4394 }
4403 4395*/
4404 if (UsePhysics) 4396 if (UsePhysics)
4405 { 4397 {
4406 AddFlag(PrimFlags.Physics); 4398 AddFlag(PrimFlags.Physics);
4399/*
4407 if (!wasUsingPhysics) 4400 if (!wasUsingPhysics)
4408 { 4401 {
4409 DoPhysicsPropertyUpdate(UsePhysics, false); 4402 DoPhysicsPropertyUpdate(UsePhysics, false);
@@ -4416,84 +4409,99 @@ namespace OpenSim.Region.Framework.Scenes
4416 } 4409 }
4417 } 4410 }
4418 } 4411 }
4412 */
4419 } 4413 }
4420 else 4414 else
4421 { 4415 {
4422 RemFlag(PrimFlags.Physics); 4416 RemFlag(PrimFlags.Physics);
4417/*
4423 if (wasUsingPhysics) 4418 if (wasUsingPhysics)
4424 { 4419 {
4425 DoPhysicsPropertyUpdate(UsePhysics, false); 4420 DoPhysicsPropertyUpdate(UsePhysics, false);
4426 } 4421 }
4427 } 4422*/
4423 }
4428 4424
4429 if (SetPhantom 4425 if (SetPhantom)
4430 || ParentGroup.IsAttachment 4426 AddFlag(PrimFlags.Phantom);
4427 else
4428 RemFlag(PrimFlags.Phantom);
4429
4430 if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment
4431 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4431 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4432 { 4432 {
4433 AddFlag(PrimFlags.Phantom); 4433 AddFlag(PrimFlags.Phantom);
4434 4434
4435 Velocity = new Vector3(0, 0, 0);
4436 Acceleration = new Vector3(0, 0, 0);
4437 if (ParentGroup.RootPart == this)
4438 AngularVelocity = new Vector3(0, 0, 0);
4439
4435 if (PhysActor != null) 4440 if (PhysActor != null)
4441 {
4442 ParentGroup.Scene.RemovePhysicalPrim(1);
4436 RemoveFromPhysics(); 4443 RemoveFromPhysics();
4444 }
4437 } 4445 }
4438 else // Not phantom 4446 else
4439 { 4447 {
4440 RemFlag(PrimFlags.Phantom);
4441
4442 if (ParentGroup.Scene == null) 4448 if (ParentGroup.Scene == null)
4443 return; 4449 return;
4444 4450
4445 if (ParentGroup.Scene.CollidablePrims && PhysActor == null) 4451 if (ParentGroup.Scene.CollidablePrims)
4446 { 4452 {
4447 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 4453 if (PhysActor == null)
4448 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4454 {
4449 string.Format("{0}/{1}", Name, UUID), 4455 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4450 Shape, 4456 string.Format("{0}/{1}", Name, UUID),
4451 AbsolutePosition, 4457 Shape,
4452 Scale, 4458 AbsolutePosition,
4453// RotationOffset, 4459 Scale,
4454 GetWorldRotation(), //physics wants world rotation like all other functions send 4460 GetWorldRotation(), //physics wants world rotation like all other functions send
4455 UsePhysics, 4461 UsePhysics,
4456 m_localId); 4462 SetPhantom,
4463 m_localId);
4457 4464
4458 PhysActor.SetMaterial(Material); 4465 PhysActor.SetMaterial(Material);
4466
4467 // if root part apply vehicle
4468 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4469 m_vehicle.SetVehicle(PhysActor);
4459 4470
4460 // if root part apply vehicle 4471 DoPhysicsPropertyUpdate(UsePhysics, true);
4461 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4462 m_vehicle.SetVehicle(PhysActor);
4463 4472
4464 DoPhysicsPropertyUpdate(UsePhysics, true); 4473 if (!ParentGroup.IsDeleted)
4474 {
4475 if (LocalId == ParentGroup.RootPart.LocalId)
4476 {
4477 ParentGroup.CheckSculptAndLoad();
4478 }
4479 }
4465 4480
4466 if (!ParentGroup.IsDeleted) 4481 if (
4467 { 4482 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4468 if (LocalId == ParentGroup.RootPart.LocalId) 4483 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4484 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4485 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4486 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4487 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4488 (CollisionSound != UUID.Zero)
4489 )
4469 { 4490 {
4470 ParentGroup.CheckSculptAndLoad(); 4491 PhysActor.OnCollisionUpdate += PhysicsCollision;
4492 PhysActor.SubscribeEvents(1000);
4471 } 4493 }
4472 } 4494 }
4473 4495 else // it already has a physical representation
4474 if (
4475 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4476 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4477 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4478 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4479 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4480 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4481 (CollisionSound != UUID.Zero)
4482 )
4483 { 4496 {
4484 PhysActor.OnCollisionUpdate += PhysicsCollision; 4497 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4485 PhysActor.SubscribeEvents(1000);
4486 }
4487 }
4488 else // it already has a physical representation
4489 {
4490 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4491 4498
4492 if (!ParentGroup.IsDeleted) 4499 if (!ParentGroup.IsDeleted)
4493 {
4494 if (LocalId == ParentGroup.RootPart.LocalId)
4495 { 4500 {
4496 ParentGroup.CheckSculptAndLoad(); 4501 if (LocalId == ParentGroup.RootPart.LocalId)
4502 {
4503 ParentGroup.CheckSculptAndLoad();
4504 }
4497 } 4505 }
4498 } 4506 }
4499 } 4507 }
@@ -4509,7 +4517,7 @@ namespace OpenSim.Region.Framework.Scenes
4509 if (this.PhysActor != null) 4517 if (this.PhysActor != null)
4510 { 4518 {
4511 PhysActor.SetVolumeDetect(1); 4519 PhysActor.SetVolumeDetect(1);
4512 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4520// AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4513 this.VolumeDetectActive = true; 4521 this.VolumeDetectActive = true;
4514 } 4522 }
4515 } 4523 }
@@ -4517,8 +4525,7 @@ namespace OpenSim.Region.Framework.Scenes
4517 { 4525 {
4518 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4526 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4519 // (mumbles, well, at least if you have infinte CPU powers :-)) 4527 // (mumbles, well, at least if you have infinte CPU powers :-))
4520 PhysicsActor pa = this.PhysActor; 4528 if (this.PhysActor != null)
4521 if (pa != null)
4522 { 4529 {
4523 PhysActor.SetVolumeDetect(0); 4530 PhysActor.SetVolumeDetect(0);
4524 } 4531 }