aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
authorRobert Adams2012-09-27 08:23:29 -0700
committerRobert Adams2012-09-27 22:01:52 -0700
commitf82b903deeaaf8eaa7ae5c4d4b7e917dd0a6ce7b (patch)
tree3d355254a7bcb8c447fbfef901784af7062763d4 /OpenSim/Region/Physics/BulletSPlugin
parentBulletSim: Terrain sets proper collision flags on creation. (diff)
downloadopensim-SC_OLD-f82b903deeaaf8eaa7ae5c4d4b7e917dd0a6ce7b.zip
opensim-SC_OLD-f82b903deeaaf8eaa7ae5c4d4b7e917dd0a6ce7b.tar.gz
opensim-SC_OLD-f82b903deeaaf8eaa7ae5c4d4b7e917dd0a6ce7b.tar.bz2
opensim-SC_OLD-f82b903deeaaf8eaa7ae5c4d4b7e917dd0a6ce7b.tar.xz
BulletSim: Fix linkset crash. Caused by the different body and shape
pointers at runtime and at taint-time. Now passes the body into the taint. Vehicles zero inertia when active to eliminate Bullet's contribution to vehicle motion.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs20
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs123
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs75
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs8
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs22
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs7
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs10
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs3
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs8
9 files changed, 182 insertions, 94 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs
index ff271fe..39a3421 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs
@@ -58,10 +58,22 @@ public class BS6DofConstraint : BSConstraint
58 m_world = world; 58 m_world = world;
59 m_body1 = obj1; 59 m_body1 = obj1;
60 m_body2 = obj2; 60 m_body2 = obj2;
61 m_constraint = new BulletConstraint( 61 if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero)
62 BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, 62 {
63 joinPoint, 63 world.scene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
64 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); 64 "[BULLETSIM 6DOF CONSTRAINT]", world.worldID,
65 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
66 world.scene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
67 "[BULLETSIM 6DOF CONSTRAINT]", world.worldID,
68 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
69 }
70 else
71 {
72 m_constraint = new BulletConstraint(
73 BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
74 joinPoint,
75 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
76 }
65 m_enabled = true; 77 m_enabled = true;
66 } 78 }
67 79
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 2da2331..cf33d0e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -54,18 +54,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
54{ 54{
55 public class BSDynamics 55 public class BSDynamics
56 { 56 {
57 private int frcount = 0; // Used to limit dynamics debug output to 57 private BSScene PhysicsScene { get; set; }
58 // every 100th frame 58 // the prim this dynamic controller belongs to
59 59 private BSPrim Prim { get; set; }
60 private BSScene m_physicsScene;
61 private BSPrim m_prim; // the prim this dynamic controller belongs to
62 60
63 // Vehicle properties 61 // Vehicle properties
64 private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind 62 public Vehicle Type { get; set; }
65 public Vehicle Type 63
66 {
67 get { return m_type; }
68 }
69 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier 64 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
70 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: 65 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
71 // HOVER_TERRAIN_ONLY 66 // HOVER_TERRAIN_ONLY
@@ -126,14 +121,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
126 121
127 public BSDynamics(BSScene myScene, BSPrim myPrim) 122 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 123 {
129 m_physicsScene = myScene; 124 PhysicsScene = myScene;
130 m_prim = myPrim; 125 Prim = myPrim;
131 m_type = Vehicle.TYPE_NONE; 126 Type = Vehicle.TYPE_NONE;
127 }
128
129 // Return 'true' if this vehicle is doing vehicle things
130 public bool IsActive
131 {
132 get { return Type != Vehicle.TYPE_NONE; }
132 } 133 }
133 134
134 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 135 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
135 { 136 {
136 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 137 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
137 switch (pParam) 138 switch (pParam)
138 { 139 {
139 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 140 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -232,7 +233,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
232 233
233 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) 234 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
234 { 235 {
235 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 236 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
236 switch (pParam) 237 switch (pParam)
237 { 238 {
238 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 239 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -267,7 +268,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
267 268
268 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 269 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
269 { 270 {
270 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 271 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
271 switch (pParam) 272 switch (pParam)
272 { 273 {
273 case Vehicle.REFERENCE_FRAME: 274 case Vehicle.REFERENCE_FRAME:
@@ -281,7 +282,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
281 282
282 internal void ProcessVehicleFlags(int pParam, bool remove) 283 internal void ProcessVehicleFlags(int pParam, bool remove)
283 { 284 {
284 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); 285 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove);
285 VehicleFlag parm = (VehicleFlag)pParam; 286 VehicleFlag parm = (VehicleFlag)pParam;
286 if (remove) 287 if (remove)
287 { 288 {
@@ -301,9 +302,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
301 302
302 internal void ProcessTypeChange(Vehicle pType) 303 internal void ProcessTypeChange(Vehicle pType)
303 { 304 {
304 VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); 305 VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType);
305 // Set Defaults For Type 306 // Set Defaults For Type
306 m_type = pType; 307 Type = pType;
307 switch (pType) 308 switch (pType)
308 { 309 {
309 case Vehicle.TYPE_NONE: 310 case Vehicle.TYPE_NONE:
@@ -465,26 +466,37 @@ namespace OpenSim.Region.Physics.BulletSPlugin
465 } 466 }
466 }//end SetDefaultsForType 467 }//end SetDefaultsForType
467 468
469 // Some of the properties of this prim may have changed.
470 // Do any updating needed for a vehicle
471 public void Refresh()
472 {
473 if (Type == Vehicle.TYPE_NONE) return;
474
475 // Set the prim's inertia to zero. The vehicle code handles that and this
476 // removes the torque action introduced by Bullet.
477 Vector3 inertia = Vector3.Zero;
478 BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, inertia);
479 BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr);
480 }
481
468 // One step of the vehicle properties for the next 'pTimestep' seconds. 482 // One step of the vehicle properties for the next 'pTimestep' seconds.
469 internal void Step(float pTimestep) 483 internal void Step(float pTimestep)
470 { 484 {
471 if (m_type == Vehicle.TYPE_NONE) return; 485 if (!IsActive) return;
472
473 frcount++; // used to limit debug comment output
474 if (frcount > 100)
475 frcount = 0;
476 486
477 MoveLinear(pTimestep); 487 MoveLinear(pTimestep);
478 MoveAngular(pTimestep); 488 MoveAngular(pTimestep);
479 LimitRotation(pTimestep); 489 LimitRotation(pTimestep);
480 490
481 // remember the position so next step we can limit absolute movement effects 491 // remember the position so next step we can limit absolute movement effects
482 m_lastPositionVector = m_prim.Position; 492 m_lastPositionVector = Prim.Position;
483 493
484 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 494 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
485 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); 495 Prim.LocalID, Prim.Position, Prim.Force, Prim.Velocity, Prim.RotationalVelocity);
486 }// end Step 496 }// end Step
487 497
498 // Apply the effect of the linear motor.
499 // Also does hover and float.
488 private void MoveLinear(float pTimestep) 500 private void MoveLinear(float pTimestep)
489 { 501 {
490 // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates 502 // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates
@@ -520,18 +532,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
520 m_linearMotorDirection *= keepfraction; 532 m_linearMotorDirection *= keepfraction;
521 533
522 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}", 534 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}",
523 m_prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector); 535 Prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
524 } 536 }
525 else 537 else
526 { 538 {
527 // if what remains of direction is very small, zero it. 539 // if what remains of direction is very small, zero it.
528 m_linearMotorDirection = Vector3.Zero; 540 m_linearMotorDirection = Vector3.Zero;
529 m_lastLinearVelocityVector = Vector3.Zero; 541 m_lastLinearVelocityVector = Vector3.Zero;
530 VDetailLog("{0},MoveLinear,zeroed", m_prim.LocalID); 542 VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
531 } 543 }
532 544
533 // convert requested object velocity to object relative vector 545 // convert requested object velocity to object relative vector
534 Quaternion rotq = m_prim.Orientation; 546 Quaternion rotq = Prim.Orientation;
535 m_newVelocity = m_lastLinearVelocityVector * rotq; 547 m_newVelocity = m_lastLinearVelocityVector * rotq;
536 548
537 // Add the various forces into m_dir which will be our new direction vector (velocity) 549 // Add the various forces into m_dir which will be our new direction vector (velocity)
@@ -539,7 +551,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
539 // add Gravity and Buoyancy 551 // add Gravity and Buoyancy
540 // There is some gravity, make a gravity force vector that is applied after object velocity. 552 // There is some gravity, make a gravity force vector that is applied after object velocity.
541 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; 553 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
542 Vector3 grav = m_prim.PhysicsScene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy)); 554 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (Prim.Mass * (1f - m_VehicleBuoyancy));
543 555
544 /* 556 /*
545 * RA: Not sure why one would do this 557 * RA: Not sure why one would do this
@@ -548,11 +560,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
548 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity 560 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
549 */ 561 */
550 562
551 Vector3 pos = m_prim.Position; 563 Vector3 pos = Prim.Position;
552// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); 564// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
553 565
554 // If below the terrain, move us above the ground a little. 566 // If below the terrain, move us above the ground a little.
555 float terrainHeight = m_prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 567 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
556 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. 568 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
557 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. 569 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
558 // Vector3 rotatedSize = m_prim.Size * m_prim.Orientation; 570 // Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
@@ -560,8 +572,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
560 if (pos.Z < terrainHeight) 572 if (pos.Z < terrainHeight)
561 { 573 {
562 pos.Z = terrainHeight + 2; 574 pos.Z = terrainHeight + 2;
563 m_prim.Position = pos; 575 Prim.Position = pos;
564 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", m_prim.LocalID, terrainHeight, pos); 576 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos);
565 } 577 }
566 578
567 // Check if hovering 579 // Check if hovering
@@ -570,7 +582,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
570 // We should hover, get the target height 582 // We should hover, get the target height
571 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) 583 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
572 { 584 {
573 m_VhoverTargetHeight = m_prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; 585 m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
574 } 586 }
575 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 587 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
576 { 588 {
@@ -590,7 +602,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
590 { 602 {
591 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 603 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
592 { 604 {
593 m_prim.Position = pos; 605 Prim.Position = pos;
594 } 606 }
595 } 607 }
596 else 608 else
@@ -608,7 +620,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
608 } 620 }
609 } 621 }
610 622
611 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight); 623 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", Prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight);
612 } 624 }
613 625
614 Vector3 posChange = pos - m_lastPositionVector; 626 Vector3 posChange = pos - m_lastPositionVector;
@@ -642,9 +654,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
642 } 654 }
643 if (changed) 655 if (changed)
644 { 656 {
645 m_prim.Position = pos; 657 Prim.Position = pos;
646 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 658 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
647 m_prim.LocalID, m_BlockingEndPoint, posChange, pos); 659 Prim.LocalID, m_BlockingEndPoint, posChange, pos);
648 } 660 }
649 } 661 }
650 662
@@ -664,7 +676,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
664 float postemp = (pos.Z - terrainHeight); 676 float postemp = (pos.Z - terrainHeight);
665 if (postemp > 2.5f) 677 if (postemp > 2.5f)
666 grav.Z = (float)(grav.Z * 1.037125); 678 grav.Z = (float)(grav.Z * 1.037125);
667 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); 679 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", Prim.LocalID, grav);
668 } 680 }
669 if ((m_flags & (VehicleFlag.NO_X)) != 0) 681 if ((m_flags & (VehicleFlag.NO_X)) != 0)
670 m_newVelocity.X = 0; 682 m_newVelocity.X = 0;
@@ -674,7 +686,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
674 m_newVelocity.Z = 0; 686 m_newVelocity.Z = 0;
675 687
676 // Apply velocity 688 // Apply velocity
677 m_prim.Velocity = m_newVelocity; 689 Prim.Velocity = m_newVelocity;
678 // apply gravity force 690 // apply gravity force
679 // Why is this set here? The physics engine already does gravity. 691 // Why is this set here? The physics engine already does gravity.
680 // m_prim.AddForce(grav, false); 692 // m_prim.AddForce(grav, false);
@@ -684,10 +696,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
684 m_lastLinearVelocityVector *= keepFraction; 696 m_lastLinearVelocityVector *= keepFraction;
685 697
686 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}", 698 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}",
687 m_prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction); 699 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction);
688 700
689 } // end MoveLinear() 701 } // end MoveLinear()
690 702
703 // Apply the effect of the angular motor.
691 private void MoveAngular(float pTimestep) 704 private void MoveAngular(float pTimestep)
692 { 705 {
693 // m_angularMotorDirection // angular velocity requested by LSL motor 706 // m_angularMotorDirection // angular velocity requested by LSL motor
@@ -699,7 +712,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
699 // m_lastAngularVelocity // what was last applied to body 712 // m_lastAngularVelocity // what was last applied to body
700 713
701 // Get what the body is doing, this includes 'external' influences 714 // Get what the body is doing, this includes 'external' influences
702 Vector3 angularVelocity = m_prim.RotationalVelocity; 715 Vector3 angularVelocity = Prim.RotationalVelocity;
703 716
704 if (m_angularMotorApply > 0) 717 if (m_angularMotorApply > 0)
705 { 718 {
@@ -716,7 +729,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
716 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); 729 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
717 730
718 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}", 731 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}",
719 m_prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); 732 Prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
720 733
721 // This is done so that if script request rate is less than phys frame rate the expected 734 // This is done so that if script request rate is less than phys frame rate the expected
722 // velocity may still be acheived. 735 // velocity may still be acheived.
@@ -737,7 +750,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
737 { 750 {
738 float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep); 751 float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep);
739 // get present body rotation 752 // get present body rotation
740 Quaternion rotq = m_prim.Orientation; 753 Quaternion rotq = Prim.Orientation;
741 // make a vector pointing up 754 // make a vector pointing up
742 Vector3 verterr = Vector3.Zero; 755 Vector3 verterr = Vector3.Zero;
743 verterr.Z = 1.0f; 756 verterr.Z = 1.0f;
@@ -767,7 +780,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
767 vertattr.Y += bounce * angularVelocity.Y; 780 vertattr.Y += bounce * angularVelocity.Y;
768 781
769 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 782 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
770 m_prim.LocalID, verterr, bounce, vertattr); 783 Prim.LocalID, verterr, bounce, vertattr);
771 784
772 } // else vertical attractor is off 785 } // else vertical attractor is off
773 786
@@ -784,13 +797,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
784 { 797 {
785 m_lastAngularVelocity.X = 0; 798 m_lastAngularVelocity.X = 0;
786 m_lastAngularVelocity.Y = 0; 799 m_lastAngularVelocity.Y = 0;
787 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 800 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
788 } 801 }
789 802
790 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 803 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
791 { 804 {
792 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 805 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
793 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 806 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
794 } 807 }
795 808
796 // apply friction 809 // apply friction
@@ -798,14 +811,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
798 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; 811 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
799 812
800 // Apply to the body 813 // Apply to the body
801 m_prim.RotationalVelocity = m_lastAngularVelocity; 814 Prim.RotationalVelocity = m_lastAngularVelocity;
802 815
803 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); 816 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity);
804 } //end MoveAngular 817 } //end MoveAngular
805 818
806 internal void LimitRotation(float timestep) 819 internal void LimitRotation(float timestep)
807 { 820 {
808 Quaternion rotq = m_prim.Orientation; 821 Quaternion rotq = Prim.Orientation;
809 Quaternion m_rot = rotq; 822 Quaternion m_rot = rotq;
810 bool changed = false; 823 bool changed = false;
811 if (m_RollreferenceFrame != Quaternion.Identity) 824 if (m_RollreferenceFrame != Quaternion.Identity)
@@ -840,8 +853,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
840 } 853 }
841 if (changed) 854 if (changed)
842 { 855 {
843 m_prim.Orientation = m_rot; 856 Prim.Orientation = m_rot;
844 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", m_prim.LocalID, rotq, m_rot); 857 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot);
845 } 858 }
846 859
847 } 860 }
@@ -849,8 +862,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
849 // Invoke the detailed logger and output something if it's enabled. 862 // Invoke the detailed logger and output something if it's enabled.
850 private void VDetailLog(string msg, params Object[] args) 863 private void VDetailLog(string msg, params Object[] args)
851 { 864 {
852 if (m_prim.PhysicsScene.VehicleLoggingEnabled) 865 if (Prim.PhysicsScene.VehicleLoggingEnabled)
853 m_prim.PhysicsScene.PhysicsLogging.Write(msg, args); 866 Prim.PhysicsScene.PhysicsLogging.Write(msg, args);
854 } 867 }
855 } 868 }
856} 869}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 84a7fac..6967108 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -92,7 +92,9 @@ public class BSLinkset
92 { 92 {
93 lock (m_linksetActivityLock) 93 lock (m_linksetActivityLock)
94 { 94 {
95 AddChildToLinkset(child); 95 // Don't add the root to its own linkset
96 if (!IsRoot(child))
97 AddChildToLinkset(child);
96 } 98 }
97 return this; 99 return this;
98 } 100 }
@@ -106,6 +108,17 @@ public class BSLinkset
106 { 108 {
107 if (IsRoot(child)) 109 if (IsRoot(child))
108 { 110 {
111 // Cannot remove the root from a linkset.
112 return this;
113 }
114
115 RemoveChildFromLinkset(child);
116
117 /* Alternate implementation that destroys the linkset of the root is removed.
118 * This fails because items are added and removed from linksets to build shapes.
119 * Code left for reference.
120 if (IsRoot(child))
121 {
109 // if root of linkset, take the linkset apart 122 // if root of linkset, take the linkset apart
110 while (m_children.Count > 0) 123 while (m_children.Count > 0)
111 { 124 {
@@ -120,6 +133,7 @@ public class BSLinkset
120 // Just removing a child from an existing linkset 133 // Just removing a child from an existing linkset
121 RemoveChildFromLinkset(child); 134 RemoveChildFromLinkset(child);
122 } 135 }
136 */
123 } 137 }
124 138
125 // The child is down to a linkset of just itself 139 // The child is down to a linkset of just itself
@@ -308,12 +322,16 @@ public class BSLinkset
308 { 322 {
309 m_children.Add(child); 323 m_children.Add(child);
310 324
311 BSPhysObject rootx = LinksetRoot; // capture the root as of now 325 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
326 BulletBody rootBodyx = LinksetRoot.BSBody;
312 BSPhysObject childx = child; 327 BSPhysObject childx = child;
328 BulletBody childBodyx = child.BSBody;
329
313 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 330 PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
314 { 331 {
315 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); 332 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
316 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child 333 // build the physical binding between me and the child
334 PhysicallyLinkAChildToRoot(rootx, rootBodyx, childx, childBodyx);
317 }); 335 });
318 } 336 }
319 return; 337 return;
@@ -323,7 +341,7 @@ public class BSLinkset
323 // This is not being called by the child so we have to make sure the child doesn't think 341 // This is not being called by the child so we have to make sure the child doesn't think
324 // it's still connected to the linkset. 342 // it's still connected to the linkset.
325 // Normal OpenSimulator operation will never do this because other SceneObjectPart information 343 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
326 // has to be updated also (like pointer to prim's parent). 344 // also has to be updated (like pointer to prim's parent).
327 private void RemoveChildFromOtherLinkset(BSPhysObject pchild) 345 private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
328 { 346 {
329 pchild.Linkset = new BSLinkset(PhysicsScene, pchild); 347 pchild.Linkset = new BSLinkset(PhysicsScene, pchild);
@@ -336,13 +354,15 @@ public class BSLinkset
336 { 354 {
337 if (m_children.Remove(child)) 355 if (m_children.Remove(child))
338 { 356 {
339 BSPhysObject rootx = LinksetRoot; // capture the root as of now 357 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
358 BulletBody rootBodyx = LinksetRoot.BSBody;
340 BSPhysObject childx = child; 359 BSPhysObject childx = child;
360 BulletBody childBodyx = child.BSBody;
341 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 361 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
342 { 362 {
343 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); 363 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
344 364
345 PhysicallyUnlinkAChildFromRoot(rootx, childx); 365 PhysicallyUnlinkAChildFromRoot(rootx, rootBodyx, childx, childBodyx);
346 RecomputeLinksetConstraintVariables(); 366 RecomputeLinksetConstraintVariables();
347 }); 367 });
348 368
@@ -357,7 +377,8 @@ public class BSLinkset
357 377
358 // Create a constraint between me (root of linkset) and the passed prim (the child). 378 // Create a constraint between me (root of linkset) and the passed prim (the child).
359 // Called at taint time! 379 // Called at taint time!
360 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 380 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BulletBody rootBody,
381 BSPhysObject childPrim, BulletBody childBody)
361 { 382 {
362 // Zero motion for children so they don't interpolate 383 // Zero motion for children so they don't interpolate
363 childPrim.ZeroMotion(); 384 childPrim.ZeroMotion();
@@ -371,16 +392,32 @@ public class BSLinkset
371 392
372 // create a constraint that allows no freedom of movement between the two objects 393 // create a constraint that allows no freedom of movement between the two objects
373 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 394 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
374 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", 395 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
375 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); 396 rootPrim.LocalID,
397 rootPrim.LocalID, rootBody.ptr.ToString("X"),
398 childPrim.LocalID, childBody.ptr.ToString("X"),
399 rootPrim.Position, childPrim.Position, midPoint);
400
401 // There is great subtlty in these paramters. Notice the check for a ptr of zero.
402 // We pass the BulletBody structure into the taint in order to capture the pointer
403 // of the body at the time of constraint creation. This doesn't work for the very first
404 // construction because there is no body yet. The body
405 // is constructed later at taint time. Thus we use the body address at time of the
406 // taint creation but, if it is zero, use what's in the prim at the moment.
407 // There is a possible race condition since shape can change without a taint call
408 // (like changing to a mesh that is already constructed). The fix for that would be
409 // to only change BSShape at taint time thus syncronizing these operations at
410 // the cost of efficiency and lag.
376 BS6DofConstraint constrain = new BS6DofConstraint( 411 BS6DofConstraint constrain = new BS6DofConstraint(
377 PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, 412 PhysicsScene.World,
413 rootBody.ptr == IntPtr.Zero ? rootPrim.BSBody : rootBody,
414 childBody.ptr == IntPtr.Zero ? childPrim.BSBody : childBody,
378 midPoint, 415 midPoint,
379 true, 416 true,
380 true 417 true
381 ); 418 );
382 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 419 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
383 * Using the midpoint is easier since it lets the Bullet code use the transforms 420 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
384 * of the objects. 421 * of the objects.
385 * Code left as a warning to future programmers. 422 * Code left as a warning to future programmers.
386 // ================================================================================== 423 // ==================================================================================
@@ -433,19 +470,26 @@ public class BSLinkset
433 } 470 }
434 471
435 // Remove linkage between myself and a particular child 472 // Remove linkage between myself and a particular child
473 // The root and child bodies are passed in because we need to remove the constraint between
474 // the bodies that were at unlink time.
436 // Called at taint time! 475 // Called at taint time!
437 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 476 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BulletBody rootBody,
477 BSPhysObject childPrim, BulletBody childBody)
438 { 478 {
439 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 479 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
480 rootPrim.LocalID,
481 rootPrim.LocalID, rootBody.ptr.ToString("X"),
482 childPrim.LocalID, childBody.ptr.ToString("X"));
440 483
441 // Find the constraint for this link and get rid of it from the overall collection and from my list 484 // Find the constraint for this link and get rid of it from the overall collection and from my list
442 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); 485 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootBody, childBody);
443 486
444 // Make the child refresh its location 487 // Make the child refresh its location
445 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr); 488 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr);
446 } 489 }
447 490
448 // Remove linkage between myself and any possible children I might have 491 /*
492 // Remove linkage between myself and any possible children I might have.
449 // Called at taint time! 493 // Called at taint time!
450 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) 494 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
451 { 495 {
@@ -453,6 +497,7 @@ public class BSLinkset
453 497
454 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); 498 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody);
455 } 499 }
500 */
456 501
457 // Invoke the detailed logger and output something if it's enabled. 502 // Invoke the detailed logger and output something if it's enabled.
458 private void DetailLog(string msg, params Object[] args) 503 private void DetailLog(string msg, params Object[] args)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 4f83adc..df95625 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -135,8 +135,11 @@ public abstract class BSPhysObject : PhysicsActor
135 // collision event to make collision_end work. 135 // collision event to make collision_end work.
136 // Called at taint time from within the Step() function thus no locking problems 136 // Called at taint time from within the Step() function thus no locking problems
137 // with CollisionCollection and ObjectsWithNoMoreCollisions. 137 // with CollisionCollection and ObjectsWithNoMoreCollisions.
138 public virtual void SendCollisions() 138 // Return 'true' if there were some actual collisions passed up
139 public virtual bool SendCollisions()
139 { 140 {
141 bool ret = true;
142
140 // throttle the collisions to the number of milliseconds specified in the subscription 143 // throttle the collisions to the number of milliseconds specified in the subscription
141 int nowTime = PhysicsScene.SimulationNowTime; 144 int nowTime = PhysicsScene.SimulationNowTime;
142 if (nowTime >= NextCollisionOkTime) 145 if (nowTime >= NextCollisionOkTime)
@@ -148,7 +151,7 @@ public abstract class BSPhysObject : PhysicsActor
148 if (CollisionCollection.Count == 0) 151 if (CollisionCollection.Count == 0)
149 { 152 {
150 // If I have no collisions this time, remove me from the list of objects with collisions. 153 // If I have no collisions this time, remove me from the list of objects with collisions.
151 PhysicsScene.ObjectsWithNoMoreCollisions.Add(this); 154 ret = false;
152 } 155 }
153 156
154 // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); 157 // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
@@ -158,6 +161,7 @@ public abstract class BSPhysObject : PhysicsActor
158 // Make sure we don't have a handle to that one and that a new one is used for next time. 161 // Make sure we don't have a handle to that one and that a new one is used for next time.
159 CollisionCollection = new CollisionEventUpdate(); 162 CollisionCollection = new CollisionEventUpdate();
160 } 163 }
164 return ret;
161 } 165 }
162 166
163 // Subscribe for collision events. 167 // Subscribe for collision events.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 68a153e..17ba85a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -507,6 +507,9 @@ public sealed class BSPrim : BSPhysObject
507 // Set up the object physicalness (does gravity and collisions move this object) 507 // Set up the object physicalness (does gravity and collisions move this object)
508 MakeDynamic(IsStatic); 508 MakeDynamic(IsStatic);
509 509
510 // Do any vehicle stuff
511 _vehicle.Refresh();
512
510 // Arrange for collision events if the simulator wants them 513 // Arrange for collision events if the simulator wants them
511 EnableCollisions(SubscribedEvents()); 514 EnableCollisions(SubscribedEvents());
512 515
@@ -556,9 +559,8 @@ public sealed class BSPrim : BSPhysObject
556 BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); 559 BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
557 // There can be special things needed for implementing linksets 560 // There can be special things needed for implementing linksets
558 Linkset.MakeStatic(this); 561 Linkset.MakeStatic(this);
559 // The activation state is 'sleeping' so Bullet will not try to act on it 562 // The activation state is 'disabled' so Bullet will not try to act on it
560 BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); 563 BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION);
561 // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION);
562 564
563 BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; 565 BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter;
564 BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask; 566 BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask;
@@ -577,7 +579,8 @@ public sealed class BSPrim : BSPhysObject
577 579
578 // A dynamic object has mass 580 // A dynamic object has mass
579 IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); 581 IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr);
580 OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass); 582 OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Mass);
583 // OMV.Vector3 inertia = OMV.Vector3.Zero;
581 BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); 584 BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia);
582 BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); 585 BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
583 586
@@ -587,10 +590,12 @@ public sealed class BSPrim : BSPhysObject
587 BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); 590 BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
588 BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); 591 BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
589 592
590 // There can be special things needed for implementing linksets 593 // There can be special things needed for implementing linksets.
591 Linkset.MakeDynamic(this); 594 Linkset.MakeDynamic(this);
592 595
593 // Force activation of the object so Bullet will act on it. 596 // Force activation of the object so Bullet will act on it.
597 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
598 BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING);
594 BulletSimAPI.Activate2(BSBody.ptr, true); 599 BulletSimAPI.Activate2(BSBody.ptr, true);
595 600
596 BSBody.collisionFilter = CollisionFilterGroups.ObjectFilter; 601 BSBody.collisionFilter = CollisionFilterGroups.ObjectFilter;
@@ -1457,9 +1462,16 @@ public sealed class BSPrim : BSPhysObject
1457 ShapeData shapeData; 1462 ShapeData shapeData;
1458 FillShapeInfo(out shapeData); 1463 FillShapeInfo(out shapeData);
1459 1464
1465 // Undo me from any possible linkset so, if body is rebuilt, the link will get restored.
1466 // NOTE that the new linkset is not set. This saves the handle to the linkset
1467 // so we can add ourselves back when shape mangling is complete.
1468 Linkset.RemoveMeFromLinkset(this);
1469
1460 // Create the correct physical representation for this type of object. 1470 // Create the correct physical representation for this type of object.
1461 // Updates BSBody and BSShape with the new information. 1471 // Updates BSBody and BSShape with the new information.
1462 PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs); 1472 PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs);
1473
1474 Linkset = Linkset.AddMeToLinkset(this);
1463 1475
1464 // Make sure the properties are set on the new object 1476 // Make sure the properties are set on the new object
1465 UpdatePhysicalParameters(); 1477 UpdatePhysicalParameters();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index e8c628c..44a249c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -544,12 +544,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters
544 544
545 // The above SendCollision's batch up the collisions on the objects. 545 // The above SendCollision's batch up the collisions on the objects.
546 // Now push the collisions into the simulator. 546 // Now push the collisions into the simulator.
547 // If the object is done colliding, it will add itself to the ObjectsWithNoMoreCollisions list.
548 if (ObjectsWithCollisions.Count > 0) 547 if (ObjectsWithCollisions.Count > 0)
549 { 548 {
550 foreach (BSPhysObject bsp in ObjectsWithCollisions) 549 foreach (BSPhysObject bsp in ObjectsWithCollisions)
551 if (!m_avatars.Contains(bsp)) // don't call avatars twice 550 if (!m_avatars.Contains(bsp)) // don't call avatars twice
552 bsp.SendCollisions(); 551 if (!bsp.SendCollisions())
552 {
553 // If the object is done colliding, see that it's removed from the colliding list
554 ObjectsWithNoMoreCollisions.Add(bsp);
555 }
553 } 556 }
554 557
555 // Objects that are done colliding are removed from the ObjectsWithCollisions list. 558 // Objects that are done colliding are removed from the ObjectsWithCollisions list.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index aadb8d6..72c6df5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -498,7 +498,8 @@ public class BSShapeCollection : IDisposable
498 ulong newHullKey = ComputeShapeKey(shapeData, pbs, out lod); 498 ulong newHullKey = ComputeShapeKey(shapeData, pbs, out lod);
499 499
500 // if the hull hasn't changed, don't rebuild it 500 // if the hull hasn't changed, don't rebuild it
501 if (newHullKey == prim.BSShape.shapeKey) return false; 501 if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL)
502 return false;
502 503
503 DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", 504 DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}",
504 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); 505 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
@@ -508,11 +509,8 @@ public class BSShapeCollection : IDisposable
508 509
509 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); 510 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
510 511
511 if (!ReferenceShape(newShape)) 512 ReferenceShape(newShape);
512 { 513
513 PhysicsScene.Logger.ErrorFormat("{0} Created new hull shape but one already exists: id={1}, key={2}, refCnt={3}",
514 LogHeader, shapeData.ID, newHullKey.ToString("X"), Hulls[newHullKey].referenceCount);
515 }
516 // hulls are already scaled by the meshmerizer 514 // hulls are already scaled by the meshmerizer
517 prim.Scale = new OMV.Vector3(1f, 1f, 1f); 515 prim.Scale = new OMV.Vector3(1f, 1f, 1f);
518 prim.BSShape = newShape; 516 prim.BSShape = newShape;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 50638d6..269c3d5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -334,7 +334,8 @@ public class BSTerrainManager
334 (uint)CollisionFilterGroups.TerrainMask); 334 (uint)CollisionFilterGroups.TerrainMask);
335 335
336 // Make sure the new shape is processed. 336 // Make sure the new shape is processed.
337 BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true); 337 // BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true);
338 BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
338 339
339 m_terrainModified = true; 340 m_terrainModified = true;
340 }; 341 };
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 6910050..2d65a35 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -369,16 +369,16 @@ public enum CollisionFilterGroups : uint
369 BSolidFilter = 1 << 13, 369 BSolidFilter = 1 << 13,
370 370
371 // The collsion filters and masked are defined in one place -- don't want them scattered 371 // The collsion filters and masked are defined in one place -- don't want them scattered
372 AvatarFilter = BDefaultFilter | BCharacterFilter | BSolidFilter, 372 AvatarFilter = BCharacterFilter,
373 AvatarMask = BAllFilter, 373 AvatarMask = BAllFilter,
374 ObjectFilter = BDefaultFilter | BSolidFilter, 374 ObjectFilter = BSolidFilter,
375 ObjectMask = BAllFilter, 375 ObjectMask = BAllFilter,
376 StaticObjectFilter = BDefaultFilter | BStaticFilter | BSolidFilter, 376 StaticObjectFilter = BStaticFilter,
377 StaticObjectMask = BAllFilter, 377 StaticObjectMask = BAllFilter,
378 VolumeDetectFilter = BSensorTrigger, 378 VolumeDetectFilter = BSensorTrigger,
379 VolumeDetectMask = ~BSensorTrigger, 379 VolumeDetectMask = ~BSensorTrigger,
380 TerrainFilter = BTerrainFilter, 380 TerrainFilter = BTerrainFilter,
381 TerrainMask = BAllFilter, 381 TerrainMask = BAllFilter & ~BStaticFilter,
382 GroundPlaneFilter = BAllFilter, 382 GroundPlaneFilter = BAllFilter,
383 GroundPlaneMask = BAllFilter 383 GroundPlaneMask = BAllFilter
384 384