aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs3
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs1
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs76
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs1
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs140
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs1
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs1
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs1
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActors.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs19
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs92
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs140
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs28
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs90
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs40
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs104
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs84
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs345
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs213
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs34
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs219
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs19
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs19
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs205
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/Physics/Manager/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/Physics/Manager/NullPhysicsScene.cs3
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs10
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs4
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs18
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs15
-rw-r--r--OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs4
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs15
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs8
-rw-r--r--OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSCharacter.cs7
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSPrim.cs1
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSScene.cs3
46 files changed, 1619 insertions, 388 deletions
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs
index ffcb01e..7d054dd 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
55// You can specify all values by your own or you can build default build and revision 55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default): 56// numbers with the '*' character (the default):
57 57
58[assembly : AssemblyVersion("0.8.0.*")] 58[assembly : AssemblyVersion("0.8.2.*")]
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
index 0d17e0e..43fba7b 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
@@ -36,8 +36,6 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
36{ 36{
37 public class BasicActor : PhysicsActor 37 public class BasicActor : PhysicsActor
38 { 38 {
39 private Vector3 _size;
40
41 public BasicActor(Vector3 size) 39 public BasicActor(Vector3 size)
42 { 40 {
43 Size = size; 41 Size = size;
@@ -240,6 +238,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
240 238
241 public override bool PIDActive 239 public override bool PIDActive
242 { 240 {
241 get { return false; }
243 set { return; } 242 set { return; }
244 } 243 }
245 244
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs
index 47d7df3..dfe4c19 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs
@@ -251,6 +251,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
251 251
252 public override bool PIDActive 252 public override bool PIDActive
253 { 253 {
254 get { return false; }
254 set { return; } 255 set { return; }
255 } 256 }
256 257
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
index 8e40561..06a205e 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
@@ -80,10 +80,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
80 return prim; 80 return prim;
81 } 81 }
82 82
83 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 83 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
84 { 84 {
85 BasicActor act = new BasicActor(size); 85 BasicActor act = new BasicActor(size);
86 act.Position = position; 86 act.Position = position;
87 act.Velocity = velocity;
87 act.Flying = isFlying; 88 act.Flying = isFlying;
88 _actors.Add(act); 89 _actors.Add(act);
89 return act; 90 return act;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
147 terrainHeight = _heightMap[(int)actor.Position.Y * (int)m_regionExtent.Y + (int)actor.Position.X]; 148 terrainHeight = _heightMap[(int)actor.Position.Y * (int)m_regionExtent.Y + (int)actor.Position.X];
148 149
149 float height = terrainHeight + actor.Size.Z; 150 float height = terrainHeight + actor.Size.Z;
151// Console.WriteLine("height {0}, actorPosition {1}", height, actorPosition);
150 152
151 if (actor.Flying) 153 if (actor.Flying)
152 { 154 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index 17ebed2..741f8db 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
@@ -658,7 +658,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
658 IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); 658 IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z);
659 IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); 659 IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W);
660 IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); 660 IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot);
661 frame2._origin = frame1v; 661 frame2._origin = frame2v;
662 constraint.SetFrames(ref frame1, ref frame2); 662 constraint.SetFrames(ref frame1, ref frame2);
663 return true; 663 return true;
664 } 664 }
@@ -1311,7 +1311,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1311 /* TODO */ 1311 /* TODO */
1312 ConfigurationParameters[] configparms = new ConfigurationParameters[1]; 1312 ConfigurationParameters[] configparms = new ConfigurationParameters[1];
1313 configparms[0] = parms; 1313 configparms[0] = parms;
1314 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 1314 Vector3 worldExtent = maxPosition;
1315 m_maxCollisions = maxCollisions; 1315 m_maxCollisions = maxCollisions;
1316 m_maxUpdatesPerFrame = maxUpdates; 1316 m_maxUpdatesPerFrame = maxUpdates;
1317 specialCollisionObjects = new Dictionary<uint, GhostObject>(); 1317 specialCollisionObjects = new Dictionary<uint, GhostObject>();
@@ -2255,7 +2255,6 @@ private sealed class BulletConstraintXNA : BulletConstraint
2255 world.LastCollisionDesc = 0; 2255 world.LastCollisionDesc = 0;
2256 world.LastEntityProperty = 0; 2256 world.LastEntityProperty = 0;
2257 numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); 2257 numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep);
2258 int updates = 0;
2259 2258
2260 PersistentManifold contactManifold; 2259 PersistentManifold contactManifold;
2261 CollisionObject objA; 2260 CollisionObject objA;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
index 1bcf879..bde4557 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Text; 31using System.Text;
32 32
33using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
34 35
35using OMV = OpenMetaverse; 36using OMV = OpenMetaverse;
@@ -70,8 +71,7 @@ public class BSActorAvatarMove : BSActor
70 public override void Dispose() 71 public override void Dispose()
71 { 72 {
72 base.SetEnabled(false); 73 base.SetEnabled(false);
73 // Now that turned off, remove any state we have in the scene. 74 DeactivateAvatarMove();
74 Refresh();
75 } 75 }
76 76
77 // Called when physical parameters (properties set in Bullet) need to be re-applied. 77 // Called when physical parameters (properties set in Bullet) need to be re-applied.
@@ -109,6 +109,10 @@ public class BSActorAvatarMove : BSActor
109 { 109 {
110 if (m_velocityMotor != null) 110 if (m_velocityMotor != null)
111 { 111 {
112// if (targ == OMV.Vector3.Zero)
113// Util.PrintCallStack();
114//
115// Console.WriteLine("SetVelocityAndTarget, {0} {1}", vel, targ);
112 m_velocityMotor.Reset(); 116 m_velocityMotor.Reset();
113 m_velocityMotor.SetTarget(targ); 117 m_velocityMotor.SetTarget(targ);
114 m_velocityMotor.SetCurrent(vel); 118 m_velocityMotor.SetCurrent(vel);
@@ -205,6 +209,17 @@ public class BSActorAvatarMove : BSActor
205 // Flying and not colliding and velocity nearly zero. 209 // Flying and not colliding and velocity nearly zero.
206 m_controllingPrim.ZeroMotion(true /* inTaintTime */); 210 m_controllingPrim.ZeroMotion(true /* inTaintTime */);
207 } 211 }
212 else
213 {
214 //We are falling but are not touching any keys make sure not falling too fast
215 if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
216 {
217
218 OMV.Vector3 slowingForce = new OMV.Vector3(0f, 0f, BSParam.AvatarTerminalVelocity - m_controllingPrim.RawVelocity.Z) * m_controllingPrim.Mass;
219 m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, slowingForce);
220 }
221
222 }
208 } 223 }
209 224
210 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", 225 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}",
@@ -227,7 +242,6 @@ public class BSActorAvatarMove : BSActor
227 stepVelocity.Z = m_controllingPrim.RawVelocity.Z; 242 stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
228 } 243 }
229 244
230
231 // Colliding and not flying with an upward force. The avatar must be trying to jump. 245 // Colliding and not flying with an upward force. The avatar must be trying to jump.
232 if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0) 246 if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0)
233 { 247 {
@@ -253,12 +267,34 @@ public class BSActorAvatarMove : BSActor
253 } 267 }
254 else 268 else
255 { 269 {
256 // Since we're not affected by anything, whatever vertical motion the avatar has, continue that. 270
257 stepVelocity.Z = m_controllingPrim.RawVelocity.Z; 271 // Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast.
272 if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
273 {
274
275 stepVelocity.Z = BSParam.AvatarTerminalVelocity;
276 }
277 else
278 {
279 stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
280 }
258 } 281 }
259 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); 282 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
260 } 283 }
261 284
285 //Alicia: Maintain minimum height when flying.
286 // SL has a flying effect that keeps the avatar flying above the ground by some margin
287 if (m_controllingPrim.Flying)
288 {
289 float hover_height = m_physicsScene.TerrainManager.GetTerrainHeightAtXYZ(m_controllingPrim.RawPosition)
290 + BSParam.AvatarFlyingGroundMargin;
291
292 if( m_controllingPrim.Position.Z < hover_height)
293 {
294 stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce;
295 }
296 }
297
262 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. 298 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
263 OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass; 299 OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass;
264 300
@@ -304,7 +340,7 @@ public class BSActorAvatarMove : BSActor
304 // float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f; 340 // float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f;
305 // Note: there is a problem with the computation of the capsule height. Thus RawPosition is off 341 // Note: there is a problem with the computation of the capsule height. Thus RawPosition is off
306 // from the height. Revisit size and this computation when height is scaled properly. 342 // from the height. Revisit size and this computation when height is scaled properly.
307 float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) - 0.05f; 343 float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) - BSParam.AvatarStepGroundFudge;
308 float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; 344 float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;
309 345
310 // Look for a collision point that is near the character's feet and is oriented the same as the charactor is. 346 // Look for a collision point that is near the character's feet and is oriented the same as the charactor is.
@@ -326,15 +362,25 @@ public class BSActorAvatarMove : BSActor
326 if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) 362 if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
327 { 363 {
328 // This contact is within the 'near the feet' range. 364 // This contact is within the 'near the feet' range.
329 // The normal should be our contact point to the object so it is pointing away 365 // The step is presumed to be more or less vertical. Thus the Z component should
330 // thus the difference between our facing orientation and the normal should be small. 366 // be nearly horizontal.
331 OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation; 367 OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
332 OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal); 368 OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
333 float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); 369 const float PIOver2 = 1.571f; // Used to make unit vector axis into approx radian angles
334 if (diff < BSParam.AvatarStepApproachFactor) 370 // m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,avNormal={1},colNormal={2},diff={3}",
371 // m_controllingPrim.LocalID, directionFacing, touchNormal,
372 // Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)) );
373 if ((Math.Abs(directionFacing.Z) * PIOver2) < BSParam.AvatarStepAngle
374 && (Math.Abs(touchNormal.Z) * PIOver2) < BSParam.AvatarStepAngle)
335 { 375 {
336 if (highestTouchPosition.Z < touchPosition.Z) 376 // The normal should be our contact point to the object so it is pointing away
337 highestTouchPosition = touchPosition; 377 // thus the difference between our facing orientation and the normal should be small.
378 float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
379 if (diff < BSParam.AvatarStepApproachFactor)
380 {
381 if (highestTouchPosition.Z < touchPosition.Z)
382 highestTouchPosition = touchPosition;
383 }
338 } 384 }
339 } 385 }
340 } 386 }
@@ -399,8 +445,8 @@ public class BSActorAvatarMove : BSActor
399 m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement; 445 m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
400 } 446 }
401 } 447 }
402 m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs.ComputeStairCorrection,disp={1},force={2}", 448 m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs.ComputeStairCorrection,stepUp={1},isp={2},force={3}",
403 m_controllingPrim.LocalID, displacement, ret); 449 m_controllingPrim.LocalID, stepUp, displacement, ret);
404 450
405 } 451 }
406 return ret; 452 return ret;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
index 8a79809..e54c27b 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
@@ -58,6 +58,7 @@ public class BSActorHover : BSActor
58 public override void Dispose() 58 public override void Dispose()
59 { 59 {
60 Enabled = false; 60 Enabled = false;
61 DeactivateHover();
61 } 62 }
62 63
63 // Called when physical parameters (properties set in Bullet) need to be re-applied. 64 // Called when physical parameters (properties set in Bullet) need to be re-applied.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
index 8b0fdeb..3b3c161 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -36,13 +36,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public class BSActorLockAxis : BSActor 37public class BSActorLockAxis : BSActor
38{ 38{
39 BSConstraint LockAxisConstraint = null; 39 private BSConstraint LockAxisConstraint = null;
40 private bool HaveRegisteredForBeforeStepCallback = false;
41
42 // The lock access flags (which axises were locked) when the contraint was built.
43 // Used to see if locking has changed since when the constraint was built.
44 OMV.Vector3 LockAxisLinearFlags;
45 OMV.Vector3 LockAxisAngularFlags;
40 46
41 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) 47 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
42 : base(physicsScene, pObj, actorName) 48 : base(physicsScene, pObj, actorName)
43 { 49 {
44 m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); 50 m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
45 LockAxisConstraint = null; 51 LockAxisConstraint = null;
52 HaveRegisteredForBeforeStepCallback = false;
46 } 53 }
47 54
48 // BSActor.isActive 55 // BSActor.isActive
@@ -55,6 +62,8 @@ public class BSActorLockAxis : BSActor
55 // BSActor.Dispose() 62 // BSActor.Dispose()
56 public override void Dispose() 63 public override void Dispose()
57 { 64 {
65 Enabled = false;
66 UnRegisterForBeforeStepCallback();
58 RemoveAxisLockConstraint(); 67 RemoveAxisLockConstraint();
59 } 68 }
60 69
@@ -63,22 +72,28 @@ public class BSActorLockAxis : BSActor
63 // BSActor.Refresh() 72 // BSActor.Refresh()
64 public override void Refresh() 73 public override void Refresh()
65 { 74 {
66 m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}", 75 // Since the axis logging is done with a constraint, Refresh() time is good for
67 m_controllingPrim.LocalID, m_controllingPrim.LockedAngularAxis, Enabled, m_controllingPrim.IsPhysicallyActive); 76 // changing parameters but this needs to wait until the prim/linkset is physically
77 // constructed. Therefore, the constraint itself is placed at pre-step time.
78
68 // If all the axis are free, we don't need to exist 79 // If all the axis are free, we don't need to exist
69 if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree) 80 // Refresh() only turns off. Enabling is done by InitializeAxisActor()
81 // whenever parameters are changed.
82 // This leaves 'enable' free to turn off an actor when it is not wanted to run.
83 if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
84 && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
70 { 85 {
71 Enabled = false; 86 Enabled = false;
72 } 87 }
73 88
74 // If the object is physically active, add the axis locking constraint
75 if (isActive) 89 if (isActive)
76 { 90 {
77 AddAxisLockConstraint(); 91 RegisterForBeforeStepCallback();
78 } 92 }
79 else 93 else
80 { 94 {
81 RemoveAxisLockConstraint(); 95 RemoveDependencies();
96 UnRegisterForBeforeStepCallback();
82 } 97 }
83 } 98 }
84 99
@@ -88,18 +103,56 @@ public class BSActorLockAxis : BSActor
88 // BSActor.RemoveDependencies() 103 // BSActor.RemoveDependencies()
89 public override void RemoveDependencies() 104 public override void RemoveDependencies()
90 { 105 {
91 if (LockAxisConstraint != null) 106 RemoveAxisLockConstraint();
107 }
108
109 private void RegisterForBeforeStepCallback()
110 {
111 if (!HaveRegisteredForBeforeStepCallback)
92 { 112 {
93 // If a constraint is set up, remove it from the physical scene 113 m_physicsScene.BeforeStep += PhysicsScene_BeforeStep;
94 RemoveAxisLockConstraint(); 114 HaveRegisteredForBeforeStepCallback = true;
95 // Schedule a call before the next simulation step to restore the constraint. 115 }
96 m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate() 116 }
117
118 private void UnRegisterForBeforeStepCallback()
119 {
120 if (HaveRegisteredForBeforeStepCallback)
121 {
122 m_physicsScene.BeforeStep -= PhysicsScene_BeforeStep;
123 HaveRegisteredForBeforeStepCallback = false;
124 }
125 }
126
127 private void PhysicsScene_BeforeStep(float timestep)
128 {
129 // If all the axis are free, we don't need to exist
130 if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
131 && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
132 {
133 Enabled = false;
134 }
135
136 // If the object is physically active, add the axis locking constraint
137 if (isActive)
138 {
139 // Check to see if the locking parameters have changed
140 if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags
141 || m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags)
97 { 142 {
98 Refresh(); 143 // The locking has changed. Remove the old constraint and build a new one
99 }); 144 RemoveAxisLockConstraint();
145 }
146
147 AddAxisLockConstraint();
148 }
149 else
150 {
151 RemoveAxisLockConstraint();
100 } 152 }
101 } 153 }
102 154
155 // Note that this relies on being called at TaintTime
103 private void AddAxisLockConstraint() 156 private void AddAxisLockConstraint()
104 { 157 {
105 if (LockAxisConstraint == null) 158 if (LockAxisConstraint == null)
@@ -118,64 +171,43 @@ public class BSActorLockAxis : BSActor
118 LockAxisConstraint = axisConstrainer; 171 LockAxisConstraint = axisConstrainer;
119 m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); 172 m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
120 173
174 // Remember the clocking being inforced so we can notice if they have changed
175 LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis;
176 LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis;
177
121 // The constraint is tied to the world and oriented to the prim. 178 // The constraint is tied to the world and oriented to the prim.
122 179
123 // Free to move linearly in the region 180 if (!axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh))
124 OMV.Vector3 linearLow = OMV.Vector3.Zero;
125 OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
126 if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis)
127 { 181 {
128 linearLow.X = m_controllingPrim.RawPosition.X; 182 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits",
129 linearHigh.X = m_controllingPrim.RawPosition.X; 183 m_controllingPrim.LocalID);
130 } 184 }
131 if (m_controllingPrim.LockedLinearAxis.Y != BSPhysObject.FreeAxis)
132 {
133 linearLow.Y = m_controllingPrim.RawPosition.Y;
134 linearHigh.Y = m_controllingPrim.RawPosition.Y;
135 }
136 if (m_controllingPrim.LockedLinearAxis.Z != BSPhysObject.FreeAxis)
137 {
138 linearLow.Z = m_controllingPrim.RawPosition.Z;
139 linearHigh.Z = m_controllingPrim.RawPosition.Z;
140 }
141 axisConstrainer.SetLinearLimits(linearLow, linearHigh);
142 185
143 // Angular with some axis locked 186 if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh))
144 float fPI = (float)Math.PI;
145 OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
146 OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
147 if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis)
148 {
149 angularLow.X = 0f;
150 angularHigh.X = 0f;
151 }
152 if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis)
153 { 187 {
154 angularLow.Y = 0f; 188 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits",
155 angularHigh.Y = 0f; 189 m_controllingPrim.LocalID);
156 }
157 if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis)
158 {
159 angularLow.Z = 0f;
160 angularHigh.Z = 0f;
161 }
162 if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
163 {
164 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID);
165 } 190 }
166 191
167 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", 192 m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
168 m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh); 193 m_controllingPrim.LocalID,
194 m_controllingPrim.LockedLinearAxisLow,
195 m_controllingPrim.LockedLinearAxisHigh,
196 m_controllingPrim.LockedAngularAxisLow,
197 m_controllingPrim.LockedAngularAxisHigh);
169 198
170 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. 199 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
171 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); 200 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
172 201
173 axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass); 202 axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass);
203
204 RegisterForBeforeStepCallback();
174 } 205 }
175 } 206 }
176 207
177 private void RemoveAxisLockConstraint() 208 private void RemoveAxisLockConstraint()
178 { 209 {
210 UnRegisterForBeforeStepCallback();
179 if (LockAxisConstraint != null) 211 if (LockAxisConstraint != null)
180 { 212 {
181 m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); 213 m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
index bdf4bc0..1145006 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
@@ -59,6 +59,7 @@ public class BSActorMoveToTarget : BSActor
59 public override void Dispose() 59 public override void Dispose()
60 { 60 {
61 Enabled = false; 61 Enabled = false;
62 DeactivateMoveToTarget();
62 } 63 }
63 64
64 // Called when physical parameters (properties set in Bullet) need to be re-applied. 65 // Called when physical parameters (properties set in Bullet) need to be re-applied.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
index 96fa0b6..4e81363 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
@@ -58,6 +58,7 @@ public class BSActorSetForce : BSActor
58 public override void Dispose() 58 public override void Dispose()
59 { 59 {
60 Enabled = false; 60 Enabled = false;
61 DeactivateSetForce();
61 } 62 }
62 63
63 // Called when physical parameters (properties set in Bullet) need to be re-applied. 64 // Called when physical parameters (properties set in Bullet) need to be re-applied.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
index 65098e1..79e1d38 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
@@ -58,6 +58,7 @@ public class BSActorSetTorque : BSActor
58 public override void Dispose() 58 public override void Dispose()
59 { 59 {
60 Enabled = false; 60 Enabled = false;
61 DeactivateSetTorque();
61 } 62 }
62 63
63 // Called when physical parameters (properties set in Bullet) need to be re-applied. 64 // Called when physical parameters (properties set in Bullet) need to be re-applied.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
index e0ccc50..7f45e2c 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
@@ -32,12 +32,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
32{ 32{
33public class BSActorCollection 33public class BSActorCollection
34{ 34{
35 private BSScene m_physicsScene { get; set; }
36 private Dictionary<string, BSActor> m_actors; 35 private Dictionary<string, BSActor> m_actors;
37 36
38 public BSActorCollection(BSScene physicsScene) 37 public BSActorCollection()
39 { 38 {
40 m_physicsScene = physicsScene;
41 m_actors = new Dictionary<string, BSActor>(); 39 m_actors = new Dictionary<string, BSActor>();
42 } 40 }
43 public void Add(string name, BSActor actor) 41 public void Add(string name, BSActor actor)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index be6f152..8491c0f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -43,9 +43,11 @@ public enum ConstraintType : int
43 SLIDER_CONSTRAINT_TYPE, 43 SLIDER_CONSTRAINT_TYPE,
44 CONTACT_CONSTRAINT_TYPE, 44 CONTACT_CONSTRAINT_TYPE,
45 D6_SPRING_CONSTRAINT_TYPE, 45 D6_SPRING_CONSTRAINT_TYPE,
46 GEAR_CONSTRAINT_TYPE, // added in Bullet 2.82
47 FIXED_CONSTRAINT_TYPE, // added in Bullet 2.82
46 MAX_CONSTRAINT_TYPE, // last type defined by Bullet 48 MAX_CONSTRAINT_TYPE, // last type defined by Bullet
47 // 49 //
48 FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving 50 BS_FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
49} 51}
50 52
51// =============================================================================== 53// ===============================================================================
@@ -209,6 +211,21 @@ public struct HACDParams
209 public float addNeighboursDistPoints; // false 211 public float addNeighboursDistPoints; // false
210 public float addFacesPoints; // false 212 public float addFacesPoints; // false
211 public float shouldAdjustCollisionMargin; // false 213 public float shouldAdjustCollisionMargin; // false
214 // VHACD
215 public float whichHACD; // zero if Bullet HACD, non-zero says VHACD
216 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html
217 public float vHACDresolution; // 100,000 max number of voxels generated during voxelization stage
218 public float vHACDdepth; // 20 max number of clipping stages
219 public float vHACDconcavity; // 0.0025 maximum concavity
220 public float vHACDplaneDownsampling; // 4 granularity of search for best clipping plane
221 public float vHACDconvexHullDownsampling; // 4 precision of hull gen process
222 public float vHACDalpha; // 0.05 bias toward clipping along symmetry planes
223 public float vHACDbeta; // 0.05 bias toward clipping along revolution axis
224 public float vHACDgamma; // 0.00125 max concavity when merging
225 public float vHACDpca; // 0 on/off normalizing mesh before decomp
226 public float vHACDmode; // 0 0:voxel based, 1: tetrahedron based
227 public float vHACDmaxNumVerticesPerCH; // 64 max triangles per convex hull
228 public float vHACDminVolumePerCH; // 0.0001 sampling of generated convex hulls
212} 229}
213 230
214// The states a bullet collision object can have 231// The states a bullet collision object can have
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index fc18960..9c3f160 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -61,18 +61,31 @@ public sealed class BSCharacter : BSPhysObject
61 private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; 61 private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
62 62
63 private OMV.Vector3 _PIDTarget; 63 private OMV.Vector3 _PIDTarget;
64 private bool _usePID;
65 private float _PIDTau; 64 private float _PIDTau;
66 65
67 public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) 66// public override OMV.Vector3 RawVelocity
67// { get { return base.RawVelocity; }
68// set {
69// if (value != base.RawVelocity)
70// Util.PrintCallStack();
71// Console.WriteLine("Set rawvel to {0}", value);
72// base.RawVelocity = value; }
73// }
74
75 // Avatars are always complete (in the physics engine sense)
76 public override bool IsIncomplete { get { return false; } }
77
78 public BSCharacter(
79 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying)
80
68 : base(parent_scene, localID, avName, "BSCharacter") 81 : base(parent_scene, localID, avName, "BSCharacter")
69 { 82 {
70 _physicsActorType = (int)ActorTypes.Agent; 83 _physicsActorType = (int)ActorTypes.Agent;
71 RawPosition = pos; 84 RawPosition = pos;
72 85
73 _flying = isFlying; 86 _flying = isFlying;
74 RawOrientation = OMV.Quaternion.Identity; 87 RawOrientation = OMV.Quaternion.Identity;
75 RawVelocity = OMV.Vector3.Zero; 88 RawVelocity = vel;
76 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 89 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
77 Friction = BSParam.AvatarStandingFriction; 90 Friction = BSParam.AvatarStandingFriction;
78 Density = BSParam.AvatarDensity; 91 Density = BSParam.AvatarDensity;
@@ -89,13 +102,15 @@ public sealed class BSCharacter : BSPhysObject
89 // set _avatarVolume and _mass based on capsule size, _density and Scale 102 // set _avatarVolume and _mass based on capsule size, _density and Scale
90 ComputeAvatarVolumeAndMass(); 103 ComputeAvatarVolumeAndMass();
91 104
92 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6}", 105 DetailLog(
93 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); 106 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}",
107 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel);
94 108
95 // do actual creation in taint time 109 // do actual creation in taint time
96 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() 110 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
97 { 111 {
98 DetailLog("{0},BSCharacter.create,taint", LocalID); 112 DetailLog("{0},BSCharacter.create,taint", LocalID);
113
99 // New body and shape into PhysBody and PhysShape 114 // New body and shape into PhysBody and PhysShape
100 PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this); 115 PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this);
101 116
@@ -134,7 +149,6 @@ public sealed class BSCharacter : BSPhysObject
134 { 149 {
135 PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody); 150 PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
136 151
137 ZeroMotion(true);
138 ForcePosition = RawPosition; 152 ForcePosition = RawPosition;
139 153
140 // Set the velocity 154 // Set the velocity
@@ -142,6 +156,7 @@ public sealed class BSCharacter : BSPhysObject
142 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false); 156 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false);
143 157
144 ForceVelocity = RawVelocity; 158 ForceVelocity = RawVelocity;
159 TargetVelocity = RawVelocity;
145 160
146 // This will enable or disable the flying buoyancy of the avatar. 161 // This will enable or disable the flying buoyancy of the avatar.
147 // Needs to be reset especially when an avatar is recreated after crossing a region boundry. 162 // Needs to be reset especially when an avatar is recreated after crossing a region boundry.
@@ -174,15 +189,19 @@ public sealed class BSCharacter : BSPhysObject
174 PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); 189 PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody);
175 190
176 // Do this after the object has been added to the world 191 // Do this after the object has been added to the world
177 PhysBody.collisionType = CollisionType.Avatar; 192 if (BSParam.AvatarToAvatarCollisionsByDefault)
193 PhysBody.collisionType = CollisionType.Avatar;
194 else
195 PhysBody.collisionType = CollisionType.PhantomToOthersAvatar;
196
178 PhysBody.ApplyCollisionMask(PhysScene); 197 PhysBody.ApplyCollisionMask(PhysScene);
179 } 198 }
180 199
181
182 public override void RequestPhysicsterseUpdate() 200 public override void RequestPhysicsterseUpdate()
183 { 201 {
184 base.RequestPhysicsterseUpdate(); 202 base.RequestPhysicsterseUpdate();
185 } 203 }
204
186 // No one calls this method so I don't know what it could possibly mean 205 // No one calls this method so I don't know what it could possibly mean
187 public override bool Stopped { get { return false; } } 206 public override bool Stopped { get { return false; } }
188 207
@@ -263,6 +282,7 @@ public sealed class BSCharacter : BSPhysObject
263 PhysScene.PE.ClearAllForces(PhysBody); 282 PhysScene.PE.ClearAllForces(PhysBody);
264 }); 283 });
265 } 284 }
285
266 public override void ZeroAngularMotion(bool inTaintTime) 286 public override void ZeroAngularMotion(bool inTaintTime)
267 { 287 {
268 _rotationalVelocity = OMV.Vector3.Zero; 288 _rotationalVelocity = OMV.Vector3.Zero;
@@ -426,7 +446,7 @@ public sealed class BSCharacter : BSPhysObject
426 m_targetVelocity = value; 446 m_targetVelocity = value;
427 OMV.Vector3 targetVel = value; 447 OMV.Vector3 targetVel = value;
428 if (_setAlwaysRun && !_flying) 448 if (_setAlwaysRun && !_flying)
429 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f); 449 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f);
430 450
431 if (m_moveActor != null) 451 if (m_moveActor != null)
432 m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); 452 m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */);
@@ -437,32 +457,40 @@ public sealed class BSCharacter : BSPhysObject
437 get { return RawVelocity; } 457 get { return RawVelocity; }
438 set { 458 set {
439 RawVelocity = value; 459 RawVelocity = value;
440 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity); 460 OMV.Vector3 vel = RawVelocity;
461
462 DetailLog("{0}: set Velocity = {1}", LocalID, value);
463
441 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate() 464 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
442 { 465 {
443 if (m_moveActor != null) 466 if (m_moveActor != null)
444 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */); 467 m_moveActor.SetVelocityAndTarget(vel, vel, true /* inTaintTime */);
445 468
446 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity); 469 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, vel);
447 ForceVelocity = RawVelocity; 470 ForceVelocity = vel;
448 }); 471 });
449 } 472 }
450 } 473 }
474
451 public override OMV.Vector3 ForceVelocity { 475 public override OMV.Vector3 ForceVelocity {
452 get { return RawVelocity; } 476 get { return RawVelocity; }
453 set { 477 set {
454 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); 478 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity");
479// Util.PrintCallStack();
480 DetailLog("{0}: set ForceVelocity = {1}", LocalID, value);
455 481
456 RawVelocity = value; 482 RawVelocity = value;
457 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); 483 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
458 PhysScene.PE.Activate(PhysBody, true); 484 PhysScene.PE.Activate(PhysBody, true);
459 } 485 }
460 } 486 }
487
461 public override OMV.Vector3 Torque { 488 public override OMV.Vector3 Torque {
462 get { return RawTorque; } 489 get { return RawTorque; }
463 set { RawTorque = value; 490 set { RawTorque = value;
464 } 491 }
465 } 492 }
493
466 public override float CollisionScore { 494 public override float CollisionScore {
467 get { return _collisionScore; } 495 get { return _collisionScore; }
468 set { _collisionScore = value; 496 set { _collisionScore = value;
@@ -614,9 +642,9 @@ public sealed class BSCharacter : BSPhysObject
614 public override OMV.Vector3 PIDTarget { 642 public override OMV.Vector3 PIDTarget {
615 set { _PIDTarget = value; } 643 set { _PIDTarget = value; }
616 } 644 }
617 public override bool PIDActive { 645
618 set { _usePID = value; } 646 public override bool PIDActive { get; set; }
619 } 647
620 public override float PIDTau { 648 public override float PIDTau {
621 set { _PIDTau = value; } 649 set { _PIDTau = value; }
622 } 650 }
@@ -657,7 +685,7 @@ public sealed class BSCharacter : BSPhysObject
657 685
658 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) 686 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
659 { 687 {
660 OMV.Vector3 newScale; 688 OMV.Vector3 newScale = size;
661 689
662 // Bullet's capsule total height is the "passed height + radius * 2"; 690 // Bullet's capsule total height is the "passed height + radius * 2";
663 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1) 691 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
@@ -670,8 +698,6 @@ public sealed class BSCharacter : BSPhysObject
670 // for a asymmetrical capsule, other parts of the code presume it is cylindrical. 698 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
671 699
672 // Scale is multiplier of radius with one of "0.5" 700 // Scale is multiplier of radius with one of "0.5"
673 newScale.X = size.X / 2f;
674 newScale.Y = size.Y / 2f;
675 701
676 float heightAdjust = BSParam.AvatarHeightMidFudge; 702 float heightAdjust = BSParam.AvatarHeightMidFudge;
677 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) 703 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
@@ -692,8 +718,17 @@ public sealed class BSCharacter : BSPhysObject
692 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge; 718 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
693 } 719 }
694 } 720 }
695 // The total scale height is the central cylindar plus the caps on the two ends. 721 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
696 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f; 722 {
723 newScale.X = size.X / 2f;
724 newScale.Y = size.Y / 2f;
725 // The total scale height is the central cylindar plus the caps on the two ends.
726 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f;
727 }
728 else
729 {
730 newScale.Z = size.Z + heightAdjust;
731 }
697 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale); 732 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
698 733
699 // If smaller than the endcaps, just fake like we're almost that small 734 // If smaller than the endcaps, just fake like we're almost that small
@@ -737,7 +772,18 @@ public sealed class BSCharacter : BSPhysObject
737 // and will send agent updates to the clients if velocity changes by more than 772 // and will send agent updates to the clients if velocity changes by more than
738 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many 773 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
739 // extra updates. 774 // extra updates.
740 if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f)) 775 //
776 // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to
777 // avatar movement rather than removes it. The larger the threshold, the bigger the jitter.
778 // This is most noticeable in level flight and can be seen with
779 // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower
780 // bound and an upper bound, where the difference between the two is enough to trigger a large delta v update
781 // and subsequently trigger an update in ScenePresence.SendTerseUpdateToAllClients(). The cause of this cycle (feedback?)
782 // has not yet been identified.
783 //
784 // If there is a threshold below 0.4 or no threshold check at all (as in ODE), then RawVelocity stays constant and extra
785 // updates are not triggered in ScenePresence.SendTerseUpdateToAllClients().
786// if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f))
741 RawVelocity = entprop.Velocity; 787 RawVelocity = entprop.Velocity;
742 788
743 _acceleration = entprop.Acceleration; 789 _acceleration = entprop.Acceleration;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 7b98f9d..c6d6331 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -42,7 +42,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
42{ 42{
43 public sealed class BSDynamics : BSActor 43 public sealed class BSDynamics : BSActor
44 { 44 {
45#pragma warning disable 414
45 private static string LogHeader = "[BULLETSIM VEHICLE]"; 46 private static string LogHeader = "[BULLETSIM VEHICLE]";
47#pragma warning restore 414
46 48
47 // the prim this dynamic controller belongs to 49 // the prim this dynamic controller belongs to
48 private BSPrimLinkable ControllingPrim { get; set; } 50 private BSPrimLinkable ControllingPrim { get; set; }
@@ -74,8 +76,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
74 private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center 76 private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center
75 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL 77 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
76 private Vector3 m_linearFrictionTimescale = Vector3.Zero; 78 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
77 private float m_linearMotorDecayTimescale = 0; 79 private float m_linearMotorDecayTimescale = 1;
78 private float m_linearMotorTimescale = 0; 80 private float m_linearMotorTimescale = 1;
79 private Vector3 m_lastLinearVelocityVector = Vector3.Zero; 81 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
80 private Vector3 m_lastPositionVector = Vector3.Zero; 82 private Vector3 m_lastPositionVector = Vector3.Zero;
81 // private bool m_LinearMotorSetLastFrame = false; 83 // private bool m_LinearMotorSetLastFrame = false;
@@ -86,8 +88,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
86 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor 88 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
87 // private int m_angularMotorApply = 0; // application frame counter 89 // private int m_angularMotorApply = 0; // application frame counter
88 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity 90 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
89 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate 91 private float m_angularMotorTimescale = 1; // motor angular velocity ramp up rate
90 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate 92 private float m_angularMotorDecayTimescale = 1; // motor angular velocity decay rate
91 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate 93 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
92 private Vector3 m_lastAngularVelocity = Vector3.Zero; 94 private Vector3 m_lastAngularVelocity = Vector3.Zero;
93 private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body 95 private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
@@ -101,7 +103,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
101 103
102 //Banking properties 104 //Banking properties
103 private float m_bankingEfficiency = 0; 105 private float m_bankingEfficiency = 0;
104 private float m_bankingMix = 0; 106 private float m_bankingMix = 1;
105 private float m_bankingTimescale = 0; 107 private float m_bankingTimescale = 0;
106 108
107 //Hover and Buoyancy properties 109 //Hover and Buoyancy properties
@@ -122,8 +124,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
122 private float m_verticalAttractionTimescale = 510f; 124 private float m_verticalAttractionTimescale = 510f;
123 125
124 // Just some recomputed constants: 126 // Just some recomputed constants:
127#pragma warning disable 414
128 static readonly float TwoPI = ((float)Math.PI) * 2f;
129 static readonly float FourPI = ((float)Math.PI) * 4f;
125 static readonly float PIOverFour = ((float)Math.PI) / 4f; 130 static readonly float PIOverFour = ((float)Math.PI) / 4f;
126 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 131 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
132#pragma warning restore 414
127 133
128 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) 134 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
129 : base(myScene, myPrim, actorName) 135 : base(myScene, myPrim, actorName)
@@ -155,56 +161,58 @@ namespace OpenSim.Region.Physics.BulletSPlugin
155 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 161 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
156 { 162 {
157 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue); 163 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
164 float clampTemp;
165
158 switch (pParam) 166 switch (pParam)
159 { 167 {
160 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 168 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
161 m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f); 169 m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
162 break; 170 break;
163 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: 171 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
164 m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); 172 m_angularDeflectionTimescale = ClampInRange(0.25f, pValue, 120);
165 break; 173 break;
166 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: 174 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
167 m_angularMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); 175 m_angularMotorDecayTimescale = ClampInRange(0.25f, pValue, 120);
168 m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; 176 m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale;
169 break; 177 break;
170 case Vehicle.ANGULAR_MOTOR_TIMESCALE: 178 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
171 m_angularMotorTimescale = Math.Max(pValue, 0.01f); 179 m_angularMotorTimescale = ClampInRange(0.25f, pValue, 120);
172 m_angularMotor.TimeScale = m_angularMotorTimescale; 180 m_angularMotor.TimeScale = m_angularMotorTimescale;
173 break; 181 break;
174 case Vehicle.BANKING_EFFICIENCY: 182 case Vehicle.BANKING_EFFICIENCY:
175 m_bankingEfficiency = ClampInRange(-1f, pValue, 1f); 183 m_bankingEfficiency = ClampInRange(-1f, pValue, 1f);
176 break; 184 break;
177 case Vehicle.BANKING_MIX: 185 case Vehicle.BANKING_MIX:
178 m_bankingMix = Math.Max(pValue, 0.01f); 186 m_bankingMix = ClampInRange(0.01f, pValue, 1);
179 break; 187 break;
180 case Vehicle.BANKING_TIMESCALE: 188 case Vehicle.BANKING_TIMESCALE:
181 m_bankingTimescale = Math.Max(pValue, 0.01f); 189 m_bankingTimescale = ClampInRange(0.25f, pValue, 120);
182 break; 190 break;
183 case Vehicle.BUOYANCY: 191 case Vehicle.BUOYANCY:
184 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); 192 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
185 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy); 193 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
186 break; 194 break;
187 case Vehicle.HOVER_EFFICIENCY: 195 case Vehicle.HOVER_EFFICIENCY:
188 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); 196 m_VhoverEfficiency = ClampInRange(0.01f, pValue, 1f);
189 break; 197 break;
190 case Vehicle.HOVER_HEIGHT: 198 case Vehicle.HOVER_HEIGHT:
191 m_VhoverHeight = pValue; 199 m_VhoverHeight = ClampInRange(0f, pValue, 1000000f);
192 break; 200 break;
193 case Vehicle.HOVER_TIMESCALE: 201 case Vehicle.HOVER_TIMESCALE:
194 m_VhoverTimescale = Math.Max(pValue, 0.01f); 202 m_VhoverTimescale = ClampInRange(0.01f, pValue, 120);
195 break; 203 break;
196 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: 204 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
197 m_linearDeflectionEfficiency = ClampInRange(0f, pValue, 1f); 205 m_linearDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
198 break; 206 break;
199 case Vehicle.LINEAR_DEFLECTION_TIMESCALE: 207 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
200 m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); 208 m_linearDeflectionTimescale = ClampInRange(0.01f, pValue, 120);
201 break; 209 break;
202 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: 210 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
203 m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); 211 m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120);
204 m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; 212 m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale;
205 break; 213 break;
206 case Vehicle.LINEAR_MOTOR_TIMESCALE: 214 case Vehicle.LINEAR_MOTOR_TIMESCALE:
207 m_linearMotorTimescale = Math.Max(pValue, 0.01f); 215 m_linearMotorTimescale = ClampInRange(0.01f, pValue, 120);
208 m_linearMotor.TimeScale = m_linearMotorTimescale; 216 m_linearMotor.TimeScale = m_linearMotorTimescale;
209 break; 217 break;
210 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: 218 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
@@ -212,30 +220,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin
212 m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; 220 m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency;
213 break; 221 break;
214 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: 222 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
215 m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); 223 m_verticalAttractionTimescale = ClampInRange(0.01f, pValue, 120);
216 m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; 224 m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale;
217 break; 225 break;
218 226
219 // These are vector properties but the engine lets you use a single float value to 227 // These are vector properties but the engine lets you use a single float value to
220 // set all of the components to the same value 228 // set all of the components to the same value
221 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 229 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
222 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); 230 clampTemp = ClampInRange(0.01f, pValue, 120);
231 m_angularFrictionTimescale = new Vector3(clampTemp, clampTemp, clampTemp);
223 break; 232 break;
224 case Vehicle.ANGULAR_MOTOR_DIRECTION: 233 case Vehicle.ANGULAR_MOTOR_DIRECTION:
225 m_angularMotorDirection = new Vector3(pValue, pValue, pValue); 234 clampTemp = ClampInRange(-TwoPI, pValue, TwoPI);
235 m_angularMotorDirection = new Vector3(clampTemp, clampTemp, clampTemp);
226 m_angularMotor.Zero(); 236 m_angularMotor.Zero();
227 m_angularMotor.SetTarget(m_angularMotorDirection); 237 m_angularMotor.SetTarget(m_angularMotorDirection);
228 break; 238 break;
229 case Vehicle.LINEAR_FRICTION_TIMESCALE: 239 case Vehicle.LINEAR_FRICTION_TIMESCALE:
230 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); 240 clampTemp = ClampInRange(0.01f, pValue, 120);
241 m_linearFrictionTimescale = new Vector3(clampTemp, clampTemp, clampTemp);
231 break; 242 break;
232 case Vehicle.LINEAR_MOTOR_DIRECTION: 243 case Vehicle.LINEAR_MOTOR_DIRECTION:
233 m_linearMotorDirection = new Vector3(pValue, pValue, pValue); 244 clampTemp = ClampInRange(-BSParam.MaxLinearVelocity, pValue, BSParam.MaxLinearVelocity);
234 m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); 245 m_linearMotorDirection = new Vector3(clampTemp, clampTemp, clampTemp);
246 m_linearMotorDirectionLASTSET = new Vector3(clampTemp, clampTemp, clampTemp);
235 m_linearMotor.SetTarget(m_linearMotorDirection); 247 m_linearMotor.SetTarget(m_linearMotorDirection);
236 break; 248 break;
237 case Vehicle.LINEAR_MOTOR_OFFSET: 249 case Vehicle.LINEAR_MOTOR_OFFSET:
238 m_linearMotorOffset = new Vector3(pValue, pValue, pValue); 250 clampTemp = ClampInRange(-1000, pValue, 1000);
251 m_linearMotorOffset = new Vector3(clampTemp, clampTemp, clampTemp);
239 break; 252 break;
240 253
241 } 254 }
@@ -247,29 +260,46 @@ namespace OpenSim.Region.Physics.BulletSPlugin
247 switch (pParam) 260 switch (pParam)
248 { 261 {
249 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 262 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
263 pValue.X = ClampInRange(0.25f, pValue.X, 120);
264 pValue.Y = ClampInRange(0.25f, pValue.Y, 120);
265 pValue.Z = ClampInRange(0.25f, pValue.Z, 120);
250 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 266 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
251 break; 267 break;
252 case Vehicle.ANGULAR_MOTOR_DIRECTION: 268 case Vehicle.ANGULAR_MOTOR_DIRECTION:
253 // Limit requested angular speed to 2 rps= 4 pi rads/sec 269 // Limit requested angular speed to 2 rps= 4 pi rads/sec
254 pValue.X = ClampInRange(-12.56f, pValue.X, 12.56f); 270 pValue.X = ClampInRange(-FourPI, pValue.X, FourPI);
255 pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); 271 pValue.Y = ClampInRange(-FourPI, pValue.Y, FourPI);
256 pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); 272 pValue.Z = ClampInRange(-FourPI, pValue.Z, FourPI);
257 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); 273 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
258 m_angularMotor.Zero(); 274 m_angularMotor.Zero();
259 m_angularMotor.SetTarget(m_angularMotorDirection); 275 m_angularMotor.SetTarget(m_angularMotorDirection);
260 break; 276 break;
261 case Vehicle.LINEAR_FRICTION_TIMESCALE: 277 case Vehicle.LINEAR_FRICTION_TIMESCALE:
278 pValue.X = ClampInRange(0.25f, pValue.X, 120);
279 pValue.Y = ClampInRange(0.25f, pValue.Y, 120);
280 pValue.Z = ClampInRange(0.25f, pValue.Z, 120);
262 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 281 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
263 break; 282 break;
264 case Vehicle.LINEAR_MOTOR_DIRECTION: 283 case Vehicle.LINEAR_MOTOR_DIRECTION:
284 pValue.X = ClampInRange(-BSParam.MaxLinearVelocity, pValue.X, BSParam.MaxLinearVelocity);
285 pValue.Y = ClampInRange(-BSParam.MaxLinearVelocity, pValue.Y, BSParam.MaxLinearVelocity);
286 pValue.Z = ClampInRange(-BSParam.MaxLinearVelocity, pValue.Z, BSParam.MaxLinearVelocity);
265 m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); 287 m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
266 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); 288 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
267 m_linearMotor.SetTarget(m_linearMotorDirection); 289 m_linearMotor.SetTarget(m_linearMotorDirection);
268 break; 290 break;
269 case Vehicle.LINEAR_MOTOR_OFFSET: 291 case Vehicle.LINEAR_MOTOR_OFFSET:
292 // Not sure the correct range to limit this variable
293 pValue.X = ClampInRange(-1000, pValue.X, 1000);
294 pValue.Y = ClampInRange(-1000, pValue.Y, 1000);
295 pValue.Z = ClampInRange(-1000, pValue.Z, 1000);
270 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); 296 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
271 break; 297 break;
272 case Vehicle.BLOCK_EXIT: 298 case Vehicle.BLOCK_EXIT:
299 // Not sure the correct range to limit this variable
300 pValue.X = ClampInRange(-10000, pValue.X, 10000);
301 pValue.Y = ClampInRange(-10000, pValue.Y, 10000);
302 pValue.Z = ClampInRange(-10000, pValue.Z, 10000);
273 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); 303 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
274 break; 304 break;
275 } 305 }
@@ -915,7 +945,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
915 { 945 {
916 get 946 get
917 { 947 {
918 return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); 948 return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleFrameOrientation));
919 } 949 }
920 } 950 }
921 951
@@ -926,6 +956,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
926 return VehicleForwardVelocity.X; 956 return VehicleForwardVelocity.X;
927 } 957 }
928 } 958 }
959 private Quaternion VehicleFrameOrientation
960 {
961 get
962 {
963 return VehicleOrientation * m_referenceFrame;
964 }
965 }
929 966
930 #endregion // Known vehicle value functions 967 #endregion // Known vehicle value functions
931 968
@@ -1011,8 +1048,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1011 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", 1048 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
1012 ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity); 1049 ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
1013 } 1050 }
1014 else if (newVelocityLengthSq < 0.001f) 1051 else if (newVelocityLengthSq < BSParam.VehicleMinLinearVelocitySquared)
1052 {
1053 Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG
1054 VDetailLog("{0}, MoveLinear,clampMin,origVelW={1},lenSq={2}",
1055 ControllingPrim.LocalID, origVelW, newVelocityLengthSq);
1015 VehicleVelocity = Vector3.Zero; 1056 VehicleVelocity = Vector3.Zero;
1057 }
1016 1058
1017 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, VehicleVelocity ); 1059 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, VehicleVelocity );
1018 1060
@@ -1030,7 +1072,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1030 linearMotorCorrectionV -= (currentVelV * frictionFactorV); 1072 linearMotorCorrectionV -= (currentVelV * frictionFactorV);
1031 1073
1032 // Motor is vehicle coordinates. Rotate it to world coordinates 1074 // Motor is vehicle coordinates. Rotate it to world coordinates
1033 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; 1075 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleFrameOrientation;
1034 1076
1035 // If we're a ground vehicle, don't add any upward Z movement 1077 // If we're a ground vehicle, don't add any upward Z movement
1036 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) 1078 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
@@ -1072,7 +1114,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1072 linearDeflectionV *= new Vector3(1, -1, -1); 1114 linearDeflectionV *= new Vector3(1, -1, -1);
1073 1115
1074 // Correction is vehicle relative. Convert to world coordinates. 1116 // Correction is vehicle relative. Convert to world coordinates.
1075 Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation; 1117 Vector3 linearDeflectionW = linearDeflectionV * VehicleFrameOrientation;
1076 1118
1077 // Optionally, if not colliding, don't effect world downward velocity. Let falling things fall. 1119 // Optionally, if not colliding, don't effect world downward velocity. Let falling things fall.
1078 if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.HasSomeCollision) 1120 if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.HasSomeCollision)
@@ -1106,7 +1148,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1106 { 1148 {
1107 // m_VhoverEfficiency: 0=bouncy, 1=totally damped 1149 // m_VhoverEfficiency: 0=bouncy, 1=totally damped
1108 // m_VhoverTimescale: time to achieve height 1150 // m_VhoverTimescale: time to achieve height
1109 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 1151 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0 && (m_VhoverHeight > 0) && (m_VhoverTimescale < 300))
1110 { 1152 {
1111 // We should hover, get the target height 1153 // We should hover, get the target height
1112 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) 1154 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
@@ -1368,7 +1410,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1368 { 1410 {
1369 // The user wants this many radians per second angular change? 1411 // The user wants this many radians per second angular change?
1370 Vector3 origVehicleRotationalVelocity = VehicleRotationalVelocity; // DEBUG DEBUG 1412 Vector3 origVehicleRotationalVelocity = VehicleRotationalVelocity; // DEBUG DEBUG
1371 Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); 1413 Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleFrameOrientation);
1372 Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV); 1414 Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV);
1373 1415
1374 // ================================================================== 1416 // ==================================================================
@@ -1389,7 +1431,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1389 Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep); 1431 Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
1390 angularMotorContributionV -= (currentAngularV * frictionFactorW); 1432 angularMotorContributionV -= (currentAngularV * frictionFactorW);
1391 1433
1392 Vector3 angularMotorContributionW = angularMotorContributionV * VehicleOrientation; 1434 Vector3 angularMotorContributionW = angularMotorContributionV * VehicleFrameOrientation;
1393 VehicleRotationalVelocity += angularMotorContributionW; 1435 VehicleRotationalVelocity += angularMotorContributionW;
1394 1436
1395 VDetailLog("{0}, MoveAngular,angularTurning,curAngVelV={1},origVehRotVel={2},vehRotVel={3},frictFact={4}, angContribV={5},angContribW={6}", 1437 VDetailLog("{0}, MoveAngular,angularTurning,curAngVelV={1},origVehRotVel={2},vehRotVel={3},frictFact={4}, angContribV={5},angContribW={6}",
@@ -1410,7 +1452,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1410 // If vertical attaction timescale is reasonable 1452 // If vertical attaction timescale is reasonable
1411 if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1453 if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1412 { 1454 {
1413 Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation; 1455 Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleFrameOrientation;
1414 switch (BSParam.VehicleAngularVerticalAttractionAlgorithm) 1456 switch (BSParam.VehicleAngularVerticalAttractionAlgorithm)
1415 { 1457 {
1416 case 0: 1458 case 0:
@@ -1429,6 +1471,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1429 // This is only half the distance to the target so it will take 2 seconds to complete the turn. 1471 // This is only half the distance to the target so it will take 2 seconds to complete the turn.
1430 Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ); 1472 Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
1431 1473
1474 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != 0)
1475 {
1476 Vector3 vehicleForwardAxis = Vector3.UnitX * VehicleFrameOrientation;
1477 torqueVector = ProjectVector(torqueVector, vehicleForwardAxis);
1478 }
1479
1432 // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared 1480 // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
1433 Vector3 vertContributionV = torqueVector * verticalAttractionSpeed * verticalAttractionSpeed; 1481 Vector3 vertContributionV = torqueVector * verticalAttractionSpeed * verticalAttractionSpeed;
1434 1482
@@ -1450,13 +1498,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1450 1498
1451 // Create a rotation that is only the vehicle's rotation around Z 1499 // Create a rotation that is only the vehicle's rotation around Z
1452 Vector3 currentEulerW = Vector3.Zero; 1500 Vector3 currentEulerW = Vector3.Zero;
1453 VehicleOrientation.GetEulerAngles(out currentEulerW.X, out currentEulerW.Y, out currentEulerW.Z); 1501 VehicleFrameOrientation.GetEulerAngles(out currentEulerW.X, out currentEulerW.Y, out currentEulerW.Z);
1454 Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEulerW.Z); 1502 Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEulerW.Z);
1455 1503
1456 // Create the axis that is perpendicular to the up vector and the rotated up vector. 1504 // Create the axis that is perpendicular to the up vector and the rotated up vector.
1457 Vector3 differenceAxisW = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); 1505 Vector3 differenceAxisW = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleFrameOrientation);
1458 // Compute the angle between those to vectors. 1506 // Compute the angle between those to vectors.
1459 double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); 1507 double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleFrameOrientation)));
1460 // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical 1508 // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
1461 1509
1462 // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. 1510 // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
@@ -1489,7 +1537,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1489 Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG 1537 Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
1490 1538
1491 // Take a vector pointing up and convert it from world to vehicle relative coords. 1539 // Take a vector pointing up and convert it from world to vehicle relative coords.
1492 Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); 1540 Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleFrameOrientation);
1493 1541
1494 // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) 1542 // If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
1495 // is now: 1543 // is now:
@@ -1520,7 +1568,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1520 vertContributionV /= m_verticalAttractionTimescale; 1568 vertContributionV /= m_verticalAttractionTimescale;
1521 1569
1522 // Rotate the vehicle rotation to the world coordinates. 1570 // Rotate the vehicle rotation to the world coordinates.
1523 VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); 1571 VehicleRotationalVelocity += (vertContributionV * VehicleFrameOrientation);
1524 1572
1525 VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}", 1573 VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}",
1526 ControllingPrim.LocalID, 1574 ControllingPrim.LocalID,
@@ -1561,7 +1609,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1561 movingDirection *= Math.Sign(VehicleForwardSpeed); 1609 movingDirection *= Math.Sign(VehicleForwardSpeed);
1562 1610
1563 // The direction the vehicle is pointing 1611 // The direction the vehicle is pointing
1564 Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; 1612 Vector3 pointingDirection = Vector3.UnitX * VehicleFrameOrientation;
1565 //Predict where the Vehicle will be pointing after AngularVelocity change is applied. This will keep 1613 //Predict where the Vehicle will be pointing after AngularVelocity change is applied. This will keep
1566 // from overshooting and allow this correction to merge with the Vertical Attraction peacefully. 1614 // from overshooting and allow this correction to merge with the Vertical Attraction peacefully.
1567 Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); 1615 Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
@@ -1586,7 +1634,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1586 deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f); 1634 deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f);
1587 //deflectContributionV /= m_angularDeflectionTimescale; 1635 //deflectContributionV /= m_angularDeflectionTimescale;
1588 1636
1589 // VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
1590 VehicleRotationalVelocity += deflectContributionV; 1637 VehicleRotationalVelocity += deflectContributionV;
1591 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", 1638 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
1592 ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); 1639 ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
@@ -1635,7 +1682,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1635 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. 1682 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
1636 // As the vehicle rolls to the right or left, the Y value will increase from 1683 // As the vehicle rolls to the right or left, the Y value will increase from
1637 // zero (straight up) to 1 or -1 (full tilt right or left) 1684 // zero (straight up) to 1 or -1 (full tilt right or left)
1638 Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; 1685 Vector3 rollComponents = Vector3.UnitZ * VehicleFrameOrientation;
1639 1686
1640 // Figure out the yaw value for this much roll. 1687 // Figure out the yaw value for this much roll.
1641 float yawAngle = m_angularMotorDirection.X * m_bankingEfficiency; 1688 float yawAngle = m_angularMotorDirection.X * m_bankingEfficiency;
@@ -1644,7 +1691,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1644 1691
1645 // TODO: the banking effect should not go to infinity but what to limit it to? 1692 // TODO: the banking effect should not go to infinity but what to limit it to?
1646 // And what should happen when this is being added to a user defined yaw that is already PI*4? 1693 // And what should happen when this is being added to a user defined yaw that is already PI*4?
1647 mixedYawAngle = ClampInRange(-12, mixedYawAngle, 12); 1694 mixedYawAngle = ClampInRange(-FourPI, mixedYawAngle, FourPI);
1648 1695
1649 // Build the force vector to change rotation from what it is to what it should be 1696 // Build the force vector to change rotation from what it is to what it should be
1650 bankingContributionV.Z = -mixedYawAngle; 1697 bankingContributionV.Z = -mixedYawAngle;
@@ -1652,7 +1699,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1652 // Don't do it all at once. Fudge because 1 second is too fast with most user defined roll as PI*4. 1699 // Don't do it all at once. Fudge because 1 second is too fast with most user defined roll as PI*4.
1653 bankingContributionV /= m_bankingTimescale * BSParam.VehicleAngularBankingTimescaleFudge; 1700 bankingContributionV /= m_bankingTimescale * BSParam.VehicleAngularBankingTimescaleFudge;
1654 1701
1655 //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation;
1656 VehicleRotationalVelocity += bankingContributionV; 1702 VehicleRotationalVelocity += bankingContributionV;
1657 1703
1658 1704
@@ -1730,6 +1776,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1730 1776
1731 } 1777 }
1732 1778
1779 //Given a Vector and a unit vector will return the amount of the vector is on the same axis as the unit.
1780 private Vector3 ProjectVector(Vector3 vector, Vector3 onNormal)
1781 {
1782 float vectorDot = Vector3.Dot(vector, onNormal);
1783 return onNormal * vectorDot;
1784
1785 }
1786
1733 private float ClampInRange(float low, float val, float high) 1787 private float ClampInRange(float low, float val, float high)
1734 { 1788 {
1735 return Math.Max(low, Math.Min(val, high)); 1789 return Math.Max(low, Math.Min(val, high));
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 77f69a5..87eba33 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -128,6 +128,7 @@ public abstract class BSLinkset
128 m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>(); 128 m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>();
129 LinksetMass = parent.RawMass; 129 LinksetMass = parent.RawMass;
130 Rebuilding = false; 130 Rebuilding = false;
131 RebuildScheduled = false;
131 132
132 parent.ClearDisplacement(); 133 parent.ClearDisplacement();
133 } 134 }
@@ -297,8 +298,16 @@ public abstract class BSLinkset
297 298
298 // Flag denoting the linkset is in the process of being rebuilt. 299 // Flag denoting the linkset is in the process of being rebuilt.
299 // Used to know not the schedule a rebuild in the middle of a rebuild. 300 // Used to know not the schedule a rebuild in the middle of a rebuild.
301 // Because of potential update calls that could want to schedule another rebuild.
300 protected bool Rebuilding { get; set; } 302 protected bool Rebuilding { get; set; }
301 303
304 // Flag saying a linkset rebuild has been scheduled.
305 // This is turned on when the rebuild is requested and turned off when
306 // the rebuild is complete. Used to limit modifications to the
307 // linkset parameters while the linkset is in an intermediate state.
308 // Protected by a "lock(m_linsetActivityLock)" on the BSLinkset object
309 public bool RebuildScheduled { get; protected set; }
310
302 // The object is going dynamic (physical). Do any setup necessary 311 // The object is going dynamic (physical). Do any setup necessary
303 // for a dynamic linkset. 312 // for a dynamic linkset.
304 // Only the state of the passed object can be modified. The rest of the linkset 313 // Only the state of the passed object can be modified. The rest of the linkset
@@ -307,6 +316,23 @@ public abstract class BSLinkset
307 // Called at taint-time! 316 // Called at taint-time!
308 public abstract bool MakeDynamic(BSPrimLinkable child); 317 public abstract bool MakeDynamic(BSPrimLinkable child);
309 318
319 public virtual bool AllPartsComplete
320 {
321 get {
322 bool ret = true;
323 this.ForEachMember((member) =>
324 {
325 if ((!member.IsInitialized) || member.IsIncomplete || member.PrimAssetState == BSPhysObject.PrimAssetCondition.Waiting)
326 {
327 ret = false;
328 return true; // exit loop
329 }
330 return false; // continue loop
331 });
332 return ret;
333 }
334 }
335
310 // The object is going static (non-physical). Do any setup necessary 336 // The object is going static (non-physical). Do any setup necessary
311 // for a static linkset. 337 // for a static linkset.
312 // Return 'true' if any properties updated on the passed object. 338 // Return 'true' if any properties updated on the passed object.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 8f12189..cae9efa 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -37,7 +37,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
37 37
38public sealed class BSLinksetCompound : BSLinkset 38public sealed class BSLinksetCompound : BSLinkset
39{ 39{
40#pragma warning disable 414
40 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; 41 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
42#pragma warning restore 414
41 43
42 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) 44 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
43 : base(scene, parent) 45 : base(scene, parent)
@@ -98,22 +100,43 @@ public sealed class BSLinksetCompound : BSLinkset
98 // Schedule a refresh to happen after all the other taint processing. 100 // Schedule a refresh to happen after all the other taint processing.
99 private void ScheduleRebuild(BSPrimLinkable requestor) 101 private void ScheduleRebuild(BSPrimLinkable requestor)
100 { 102 {
101 DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
102 requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
103
104 // When rebuilding, it is possible to set properties that would normally require a rebuild. 103 // When rebuilding, it is possible to set properties that would normally require a rebuild.
105 // If already rebuilding, don't request another rebuild. 104 // If already rebuilding, don't request another rebuild.
106 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding. 105 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
107 if (!Rebuilding && HasAnyChildren) 106 lock (m_linksetActivityLock)
108 { 107 {
109 m_physicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate() 108 if (!RebuildScheduled && !Rebuilding && HasAnyChildren)
110 { 109 {
111 if (HasAnyChildren) 110 InternalScheduleRebuild(requestor);
112 RecomputeLinksetCompound(); 111 }
113 });
114 } 112 }
115 } 113 }
116 114
115 // Must be called with m_linksetActivityLock or race conditions will haunt you.
116 private void InternalScheduleRebuild(BSPrimLinkable requestor)
117 {
118 DetailLog("{0},BSLinksetCompound.InternalScheduleRebuild,,rebuilding={1},hasChildren={2}",
119 requestor.LocalID, Rebuilding, HasAnyChildren);
120 RebuildScheduled = true;
121 m_physicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
122 {
123 if (HasAnyChildren)
124 {
125 if (this.AllPartsComplete)
126 {
127 RecomputeLinksetCompound();
128 }
129 else
130 {
131 DetailLog("{0},BSLinksetCompound.InternalScheduleRebuild,,rescheduling because not all children complete",
132 requestor.LocalID);
133 InternalScheduleRebuild(requestor);
134 }
135 }
136 RebuildScheduled = false;
137 });
138 }
139
117 // The object is going dynamic (physical). Do any setup necessary for a dynamic linkset. 140 // The object is going dynamic (physical). Do any setup necessary for a dynamic linkset.
118 // Only the state of the passed object can be modified. The rest of the linkset 141 // Only the state of the passed object can be modified. The rest of the linkset
119 // has not yet been fully constructed. 142 // has not yet been fully constructed.
@@ -178,7 +201,10 @@ public sealed class BSLinksetCompound : BSLinkset
178 if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) 201 if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
179 { 202 {
180 // Find the physical instance of the child 203 // Find the physical instance of the child
181 if (LinksetRoot.PhysShape.HasPhysicalShape && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo)) 204 if (!RebuildScheduled // if rebuilding, let the rebuild do it
205 && !LinksetRoot.IsIncomplete // if waiting for assets or whatever, don't change
206 && LinksetRoot.PhysShape.HasPhysicalShape // there must be a physical shape assigned
207 && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo))
182 { 208 {
183 // It is possible that the linkset is still under construction and the child is not yet 209 // It is possible that the linkset is still under construction and the child is not yet
184 // inserted into the compound shape. A rebuild of the linkset in a pre-step action will 210 // inserted into the compound shape. A rebuild of the linkset in a pre-step action will
@@ -369,23 +395,47 @@ public sealed class BSLinksetCompound : BSLinkset
369 // Get a reference to the shape of the child for adding of that shape to the linkset compound shape 395 // Get a reference to the shape of the child for adding of that shape to the linkset compound shape
370 BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); 396 BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim);
371 397
372 // Offset the child shape from the center-of-mass and rotate it to vehicle relative. 398 // Offset the child shape from the center-of-mass and rotate it to root relative.
373 OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV; 399 OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV;
374 OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation; 400 OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation;
375 401
376 // Add the child shape to the compound shape being built 402 // Add the child shape to the compound shape being built
377 m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot); 403 if (childShape.physShapeInfo.HasPhysicalShape)
378 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}", 404 {
379 LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot); 405 m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot);
406 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}",
407 LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
380 408
381 // Since we are borrowing the shape of the child, disable the origional child body 409 // Since we are borrowing the shape of the child, disable the origional child body
382 if (!IsRoot(cPrim)) 410 if (!IsRoot(cPrim))
411 {
412 m_physicsScene.PE.AddToCollisionFlags(cPrim.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
413 m_physicsScene.PE.ForceActivationState(cPrim.PhysBody, ActivationState.DISABLE_SIMULATION);
414 // We don't want collisions from the old linkset children.
415 m_physicsScene.PE.RemoveFromCollisionFlags(cPrim.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
416 cPrim.PhysBody.collisionType = CollisionType.LinksetChild;
417 }
418 }
419 else
383 { 420 {
384 m_physicsScene.PE.AddToCollisionFlags(cPrim.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); 421 // The linkset must be in an intermediate state where all the children have not yet
385 m_physicsScene.PE.ForceActivationState(cPrim.PhysBody, ActivationState.DISABLE_SIMULATION); 422 // been constructed. This sometimes happens on startup when everything is getting
386 // We don't want collisions from the old linkset children. 423 // built and some shapes have to wait for assets to be read in.
387 m_physicsScene.PE.RemoveFromCollisionFlags(cPrim.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 424 // Just skip this linkset for the moment and cause the shape to be rebuilt next tick.
388 cPrim.PhysBody.collisionType = CollisionType.LinksetChild; 425 // One problem might be that the shape is broken somehow and it never becomes completely
426 // available. This might cause the rebuild to happen over and over.
427 InternalScheduleRebuild(LinksetRoot);
428 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChildWithNoShape,indx={1},cShape={2},offPos={3},offRot={4}",
429 LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
430 // Output an annoying warning. It should only happen once but if it keeps coming out,
431 // the user knows there is something wrong and will report it.
432 m_physicsScene.Logger.WarnFormat("{0} Linkset rebuild warning. If this happens more than one or two times, please report in Mantis 7191", LogHeader);
433 m_physicsScene.Logger.WarnFormat("{0} pName={1}, childIdx={2}, shape={3}",
434 LogHeader, LinksetRoot.Name, cPrim.LinksetChildIndex, childShape);
435
436 // This causes the loop to bail on building the rest of this linkset.
437 // The rebuild operation will fix it up next tick or declare the object unbuildable.
438 return true;
389 } 439 }
390 440
391 return false; // 'false' says to move onto the next child in the list 441 return false; // 'false' says to move onto the next child in the list
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index aaf92c8..4384cdc 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -78,7 +78,7 @@ public sealed class BSLinksetConstraints : BSLinkset
78 public override void ResetLink() 78 public override void ResetLink()
79 { 79 {
80 // constraintType = ConstraintType.D6_CONSTRAINT_TYPE; 80 // constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
81 constraintType = ConstraintType.FIXED_CONSTRAINT_TYPE; 81 constraintType = ConstraintType.BS_FIXED_CONSTRAINT_TYPE;
82 linearLimitLow = OMV.Vector3.Zero; 82 linearLimitLow = OMV.Vector3.Zero;
83 linearLimitHigh = OMV.Vector3.Zero; 83 linearLimitHigh = OMV.Vector3.Zero;
84 angularLimitLow = OMV.Vector3.Zero; 84 angularLimitLow = OMV.Vector3.Zero;
@@ -115,7 +115,7 @@ public sealed class BSLinksetConstraints : BSLinkset
115 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType); 115 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType);
116 switch (constraintType) 116 switch (constraintType)
117 { 117 {
118 case ConstraintType.FIXED_CONSTRAINT_TYPE: 118 case ConstraintType.BS_FIXED_CONSTRAINT_TYPE:
119 case ConstraintType.D6_CONSTRAINT_TYPE: 119 case ConstraintType.D6_CONSTRAINT_TYPE:
120 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; 120 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
121 if (constrain6dof != null) 121 if (constrain6dof != null)
@@ -179,7 +179,7 @@ public sealed class BSLinksetConstraints : BSLinkset
179 public override bool ShouldUpdateChildProperties() 179 public override bool ShouldUpdateChildProperties()
180 { 180 {
181 bool ret = true; 181 bool ret = true;
182 if (constraintType == ConstraintType.FIXED_CONSTRAINT_TYPE) 182 if (constraintType == ConstraintType.BS_FIXED_CONSTRAINT_TYPE)
183 ret = false; 183 ret = false;
184 184
185 return ret; 185 return ret;
@@ -212,20 +212,28 @@ public sealed class BSLinksetConstraints : BSLinkset
212 // When rebuilding, it is possible to set properties that would normally require a rebuild. 212 // When rebuilding, it is possible to set properties that would normally require a rebuild.
213 // If already rebuilding, don't request another rebuild. 213 // If already rebuilding, don't request another rebuild.
214 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding. 214 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
215 if (!Rebuilding && HasAnyChildren) 215 lock (this)
216 { 216 {
217 // Queue to happen after all the other taint processing 217 if (!RebuildScheduled)
218 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
219 { 218 {
220 if (HasAnyChildren) 219 if (!Rebuilding && HasAnyChildren)
221 { 220 {
222 // Constraints that have not been changed are not rebuild but make sure 221 RebuildScheduled = true;
223 // the constraint of the requestor is rebuilt. 222 // Queue to happen after all the other taint processing
224 PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor); 223 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
225 // Rebuild the linkset and all its constraints. 224 {
226 RecomputeLinksetConstraints(); 225 if (HasAnyChildren)
226 {
227 // Constraints that have not been changed are not rebuild but make sure
228 // the constraint of the requestor is rebuilt.
229 PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
230 // Rebuild the linkset and all its constraints.
231 RecomputeLinksetConstraints();
232 }
233 RebuildScheduled = false;
234 });
227 } 235 }
228 }); 236 }
229 } 237 }
230 } 238 }
231 239
@@ -363,7 +371,7 @@ public sealed class BSLinksetConstraints : BSLinkset
363 371
364 switch (linkInfo.constraintType) 372 switch (linkInfo.constraintType)
365 { 373 {
366 case ConstraintType.FIXED_CONSTRAINT_TYPE: 374 case ConstraintType.BS_FIXED_CONSTRAINT_TYPE:
367 case ConstraintType.D6_CONSTRAINT_TYPE: 375 case ConstraintType.D6_CONSTRAINT_TYPE:
368 // Relative position normalized to the root prim 376 // Relative position normalized to the root prim
369 // Essentually a vector pointing from center of rootPrim to center of li.member 377 // Essentually a vector pointing from center of rootPrim to center of li.member
@@ -536,7 +544,7 @@ public sealed class BSLinksetConstraints : BSLinkset
536 { 544 {
537 int requestedType = (int)pParams[2]; 545 int requestedType = (int)pParams[2];
538 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,requestedType={1}", LinksetRoot.LocalID, requestedType); 546 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,requestedType={1}", LinksetRoot.LocalID, requestedType);
539 if (requestedType == (int)ConstraintType.FIXED_CONSTRAINT_TYPE 547 if (requestedType == (int)ConstraintType.BS_FIXED_CONSTRAINT_TYPE
540 || requestedType == (int)ConstraintType.D6_CONSTRAINT_TYPE 548 || requestedType == (int)ConstraintType.D6_CONSTRAINT_TYPE
541 || requestedType == (int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE 549 || requestedType == (int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE
542 || requestedType == (int)ConstraintType.HINGE_CONSTRAINT_TYPE 550 || requestedType == (int)ConstraintType.HINGE_CONSTRAINT_TYPE
@@ -646,7 +654,7 @@ public sealed class BSLinksetConstraints : BSLinkset
646 case ExtendedPhysics.PHYS_PARAM_LINK_TYPE: 654 case ExtendedPhysics.PHYS_PARAM_LINK_TYPE:
647 valueInt = (int)pParams[opIndex + 1]; 655 valueInt = (int)pParams[opIndex + 1];
648 ConstraintType valueType = (ConstraintType)valueInt; 656 ConstraintType valueType = (ConstraintType)valueInt;
649 if (valueType == ConstraintType.FIXED_CONSTRAINT_TYPE 657 if (valueType == ConstraintType.BS_FIXED_CONSTRAINT_TYPE
650 || valueType == ConstraintType.D6_CONSTRAINT_TYPE 658 || valueType == ConstraintType.D6_CONSTRAINT_TYPE
651 || valueType == ConstraintType.D6_SPRING_CONSTRAINT_TYPE 659 || valueType == ConstraintType.D6_SPRING_CONSTRAINT_TYPE
652 || valueType == ConstraintType.HINGE_CONSTRAINT_TYPE 660 || valueType == ConstraintType.HINGE_CONSTRAINT_TYPE
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 834228e..6d46fe6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -54,6 +54,14 @@ public static class BSParam
54 // =================== 54 // ===================
55 // From: 55 // From:
56 56
57 /// <summary>
58 /// Set whether physics is active or not.
59 /// </summary>
60 /// <remarks>
61 /// Can be enabled and disabled to start and stop physics.
62 /// </remarks>
63 public static bool Active { get; private set; }
64
57 public static bool UseSeparatePhysicsThread { get; private set; } 65 public static bool UseSeparatePhysicsThread { get; private set; }
58 public static float PhysicsTimeStep { get; private set; } 66 public static float PhysicsTimeStep { get; private set; }
59 67
@@ -97,6 +105,7 @@ public static class BSParam
97 105
98 public static float TerrainImplementation { get; set; } 106 public static float TerrainImplementation { get; set; }
99 public static int TerrainMeshMagnification { get; private set; } 107 public static int TerrainMeshMagnification { get; private set; }
108 public static float TerrainGroundPlane { get; private set; }
100 public static float TerrainFriction { get; private set; } 109 public static float TerrainFriction { get; private set; }
101 public static float TerrainHitFraction { get; private set; } 110 public static float TerrainHitFraction { get; private set; }
102 public static float TerrainRestitution { get; private set; } 111 public static float TerrainRestitution { get; private set; }
@@ -123,22 +132,29 @@ public static class BSParam
123 public static float PhysicsUnmanLoggingFrames { get; private set; } 132 public static float PhysicsUnmanLoggingFrames { get; private set; }
124 133
125 // Avatar parameters 134 // Avatar parameters
135 public static bool AvatarToAvatarCollisionsByDefault { get; private set; }
126 public static float AvatarFriction { get; private set; } 136 public static float AvatarFriction { get; private set; }
127 public static float AvatarStandingFriction { get; private set; } 137 public static float AvatarStandingFriction { get; private set; }
128 public static float AvatarAlwaysRunFactor { get; private set; } 138 public static float AvatarAlwaysRunFactor { get; private set; }
129 public static float AvatarDensity { get; private set; } 139 public static float AvatarDensity { get; private set; }
130 public static float AvatarRestitution { get; private set; } 140 public static float AvatarRestitution { get; private set; }
141 public static int AvatarShape { get; private set; }
131 public static float AvatarCapsuleWidth { get; private set; } 142 public static float AvatarCapsuleWidth { get; private set; }
132 public static float AvatarCapsuleDepth { get; private set; } 143 public static float AvatarCapsuleDepth { get; private set; }
133 public static float AvatarCapsuleHeight { get; private set; } 144 public static float AvatarCapsuleHeight { get; private set; }
134 public static float AvatarHeightLowFudge { get; private set; } 145 public static float AvatarHeightLowFudge { get; private set; }
135 public static float AvatarHeightMidFudge { get; private set; } 146 public static float AvatarHeightMidFudge { get; private set; }
136 public static float AvatarHeightHighFudge { get; private set; } 147 public static float AvatarHeightHighFudge { get; private set; }
148 public static float AvatarFlyingGroundMargin { get; private set; }
149 public static float AvatarFlyingGroundUpForce { get; private set; }
150 public static float AvatarTerminalVelocity { get; private set; }
137 public static float AvatarContactProcessingThreshold { get; private set; } 151 public static float AvatarContactProcessingThreshold { get; private set; }
138 public static float AvatarStopZeroThreshold { get; private set; } 152 public static float AvatarStopZeroThreshold { get; private set; }
139 public static int AvatarJumpFrames { get; private set; } 153 public static int AvatarJumpFrames { get; private set; }
140 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } 154 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
141 public static float AvatarStepHeight { get; private set; } 155 public static float AvatarStepHeight { get; private set; }
156 public static float AvatarStepAngle { get; private set; }
157 public static float AvatarStepGroundFudge { get; private set; }
142 public static float AvatarStepApproachFactor { get; private set; } 158 public static float AvatarStepApproachFactor { get; private set; }
143 public static float AvatarStepForceFactor { get; private set; } 159 public static float AvatarStepForceFactor { get; private set; }
144 public static float AvatarStepUpCorrectionFactor { get; private set; } 160 public static float AvatarStepUpCorrectionFactor { get; private set; }
@@ -147,6 +163,8 @@ public static class BSParam
147 // Vehicle parameters 163 // Vehicle parameters
148 public static float VehicleMaxLinearVelocity { get; private set; } 164 public static float VehicleMaxLinearVelocity { get; private set; }
149 public static float VehicleMaxLinearVelocitySquared { get; private set; } 165 public static float VehicleMaxLinearVelocitySquared { get; private set; }
166 public static float VehicleMinLinearVelocity { get; private set; }
167 public static float VehicleMinLinearVelocitySquared { get; private set; }
150 public static float VehicleMaxAngularVelocity { get; private set; } 168 public static float VehicleMaxAngularVelocity { get; private set; }
151 public static float VehicleMaxAngularVelocitySq { get; private set; } 169 public static float VehicleMaxAngularVelocitySq { get; private set; }
152 public static float VehicleAngularDamping { get; private set; } 170 public static float VehicleAngularDamping { get; private set; }
@@ -165,6 +183,7 @@ public static class BSParam
165 public static bool VehicleEnableAngularBanking { get; private set; } 183 public static bool VehicleEnableAngularBanking { get; private set; }
166 184
167 // Convex Hulls 185 // Convex Hulls
186 // Parameters for convex hull routine that ships with Bullet
168 public static int CSHullMaxDepthSplit { get; private set; } 187 public static int CSHullMaxDepthSplit { get; private set; }
169 public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; } 188 public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; }
170 public static float CSHullConcavityThresholdPercent { get; private set; } 189 public static float CSHullConcavityThresholdPercent { get; private set; }
@@ -180,6 +199,22 @@ public static class BSParam
180 public static bool BHullAddNeighboursDistPoints { get; private set; } // false 199 public static bool BHullAddNeighboursDistPoints { get; private set; } // false
181 public static bool BHullAddFacesPoints { get; private set; } // false 200 public static bool BHullAddFacesPoints { get; private set; } // false
182 public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false 201 public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false
202 public static float WhichHACD { get; private set; } // zero if Bullet HACD, non-zero says VHACD
203 // Parameters for VHACD 2.0: http://code.google.com/p/v-hacd
204 // To enable, set both ShouldUseBulletHACD=true and WhichHACD=1
205 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html
206 public static float VHACDresolution { get; private set; } // 100,000 max number of voxels generated during voxelization stage
207 public static float VHACDdepth { get; private set; } // 20 max number of clipping stages
208 public static float VHACDconcavity { get; private set; } // 0.0025 maximum concavity
209 public static float VHACDplaneDownsampling { get; private set; } // 4 granularity of search for best clipping plane
210 public static float VHACDconvexHullDownsampling { get; private set; } // 4 precision of hull gen process
211 public static float VHACDalpha { get; private set; } // 0.05 bias toward clipping along symmetry planes
212 public static float VHACDbeta { get; private set; } // 0.05 bias toward clipping along revolution axis
213 public static float VHACDgamma { get; private set; } // 0.00125 max concavity when merging
214 public static float VHACDpca { get; private set; } // 0 on/off normalizing mesh before decomp
215 public static float VHACDmode { get; private set; } // 0 0:voxel based, 1: tetrahedron based
216 public static float VHACDmaxNumVerticesPerCH { get; private set; } // 64 max triangles per convex hull
217 public static float VHACDminVolumePerCH { get; private set; } // 0.0001 sampling of generated convex hulls
183 218
184 // Linkset implementation parameters 219 // Linkset implementation parameters
185 public static float LinksetImplementation { get; private set; } 220 public static float LinksetImplementation { get; private set; }
@@ -366,6 +401,8 @@ public static class BSParam
366 // v = value (appropriate type) 401 // v = value (appropriate type)
367 private static ParameterDefnBase[] ParameterDefinitions = 402 private static ParameterDefnBase[] ParameterDefinitions =
368 { 403 {
404 new ParameterDefn<bool>("Active", "If 'true', false then physics is not active",
405 false ),
369 new ParameterDefn<bool>("UseSeparatePhysicsThread", "If 'true', the physics engine runs independent from the simulator heartbeat", 406 new ParameterDefn<bool>("UseSeparatePhysicsThread", "If 'true', the physics engine runs independent from the simulator heartbeat",
370 false ), 407 false ),
371 new ParameterDefn<float>("PhysicsTimeStep", "If separate thread, seconds to simulate each interval", 408 new ParameterDefn<float>("PhysicsTimeStep", "If separate thread, seconds to simulate each interval",
@@ -538,9 +575,11 @@ public static class BSParam
538 (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), 575 (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ),
539 576
540 new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", 577 new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
541 (float)BSTerrainPhys.TerrainImplementation.Mesh ), 578 (float)BSTerrainPhys.TerrainImplementation.Heightmap ),
542 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , 579 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
543 2 ), 580 2 ),
581 new ParameterDefn<float>("TerrainGroundPlane", "Altitude of ground plane used to keep things from falling to infinity" ,
582 -500.0f ),
544 new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" , 583 new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" ,
545 0.3f ), 584 0.3f ),
546 new ParameterDefn<float>("TerrainHitFraction", "Distance to measure hit collisions" , 585 new ParameterDefn<float>("TerrainHitFraction", "Distance to measure hit collisions" ,
@@ -550,8 +589,10 @@ public static class BSParam
550 new ParameterDefn<float>("TerrainContactProcessingThreshold", "Distance from terrain to stop processing collisions" , 589 new ParameterDefn<float>("TerrainContactProcessingThreshold", "Distance from terrain to stop processing collisions" ,
551 0.0f ), 590 0.0f ),
552 new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" , 591 new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" ,
553 0.08f ), 592 0.04f ),
554 593
594 new ParameterDefn<bool>("AvatarToAvatarCollisionsByDefault", "Should avatars collide with other avatars by default?",
595 true),
555 new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 596 new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
556 0.2f ), 597 0.2f ),
557 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 598 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
@@ -563,6 +604,8 @@ public static class BSParam
563 3500f) , // 3.5 * 100 604 3500f) , // 3.5 * 100
564 new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 605 new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
565 0f ), 606 0f ),
607 new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh",
608 BSShapeCollection.AvatarShapeCube ) ,
566 new ParameterDefn<float>("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", 609 new ParameterDefn<float>("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
567 0.6f ) , 610 0.6f ) ,
568 new ParameterDefn<float>("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", 611 new ParameterDefn<float>("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
@@ -570,11 +613,17 @@ public static class BSParam
570 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar", 613 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar",
571 1.5f ), 614 1.5f ),
572 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 615 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
573 -0.2f ), 616 0f ),
574 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", 617 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
575 0.1f ), 618 0f ),
576 new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", 619 new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground",
577 0.1f ), 620 0f ),
621 new ParameterDefn<float>("AvatarFlyingGroundMargin", "Meters avatar is kept above the ground when flying",
622 5f ),
623 new ParameterDefn<float>("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin",
624 2.0f ),
625 new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar",
626 -54.0f ),
578 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 627 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
579 0.1f ), 628 0.1f ),
580 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped", 629 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
@@ -584,20 +633,28 @@ public static class BSParam
584 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", 633 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
585 4 ), 634 4 ),
586 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", 635 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction",
587 0.6f ) , 636 0.999f ) ,
637 new ParameterDefn<float>("AvatarStepAngle", "The angle (in radians) for a vertical surface to be considered a step",
638 0.3f ) ,
639 new ParameterDefn<float>("AvatarStepGroundFudge", "Fudge factor subtracted from avatar base when comparing collision height",
640 0.1f ) ,
588 new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", 641 new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)",
589 0.6f ), 642 2f ),
590 new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", 643 new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step",
591 1.0f ), 644 0f ),
592 new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step", 645 new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step",
593 1.0f ), 646 0.8f ),
594 new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs", 647 new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs",
595 2 ), 648 1 ),
596 649
597 new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", 650 new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle",
598 1000.0f, 651 1000.0f,
599 (s) => { return (float)VehicleMaxLinearVelocity; }, 652 (s) => { return (float)VehicleMaxLinearVelocity; },
600 (s,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySquared = v * v; } ), 653 (s,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySquared = v * v; } ),
654 new ParameterDefn<float>("VehicleMinLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle",
655 0.001f,
656 (s) => { return (float)VehicleMinLinearVelocity; },
657 (s,v) => { VehicleMinLinearVelocity = v; VehicleMinLinearVelocitySquared = v * v; } ),
601 new ParameterDefn<float>("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", 658 new ParameterDefn<float>("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle",
602 12.0f, 659 12.0f,
603 (s) => { return (float)VehicleMaxAngularVelocity; }, 660 (s) => { return (float)VehicleMaxAngularVelocity; },
@@ -709,6 +766,33 @@ public static class BSParam
709 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", 766 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
710 false ), 767 false ),
711 768
769 new ParameterDefn<float>("WhichHACD", "zero if Bullet HACD, non-zero says VHACD",
770 0f ),
771 new ParameterDefn<float>("VHACDresolution", "max number of voxels generated during voxelization stage",
772 100000f ),
773 new ParameterDefn<float>("VHACDdepth", "max number of clipping stages",
774 20f ),
775 new ParameterDefn<float>("VHACDconcavity", "maximum concavity",
776 0.0025f ),
777 new ParameterDefn<float>("VHACDplaneDownsampling", "granularity of search for best clipping plane",
778 4f ),
779 new ParameterDefn<float>("VHACDconvexHullDownsampling", "precision of hull gen process",
780 4f ),
781 new ParameterDefn<float>("VHACDalpha", "bias toward clipping along symmetry planes",
782 0.05f ),
783 new ParameterDefn<float>("VHACDbeta", "bias toward clipping along revolution axis",
784 0.05f ),
785 new ParameterDefn<float>("VHACDgamma", "max concavity when merging",
786 0.00125f ),
787 new ParameterDefn<float>("VHACDpca", "on/off normalizing mesh before decomp",
788 0f ),
789 new ParameterDefn<float>("VHACDmode", "0:voxel based, 1: tetrahedron based",
790 0f ),
791 new ParameterDefn<float>("VHACDmaxNumVerticesPerCH", "max triangles per convex hull",
792 64f ),
793 new ParameterDefn<float>("VHACDminVolumePerCH", "sampling of generated convex hulls",
794 0.0001f ),
795
712 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", 796 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
713 (float)BSLinkset.LinksetImplementation.Compound ), 797 (float)BSLinkset.LinksetImplementation.Compound ),
714 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same", 798 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same",
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index f89b376..90da7a6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -80,28 +80,27 @@ public abstract class BSPhysObject : PhysicsActor
80 Name = name; // PhysicsActor also has the name of the object. Someday consolidate. 80 Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
81 TypeName = typeName; 81 TypeName = typeName;
82 82
83 // The collection of things that push me around 83 // Oddity if object is destroyed and recreated very quickly it could still have the old body.
84 PhysicalActors = new BSActorCollection(PhysScene); 84 if (!PhysBody.HasPhysicalBody)
85 PhysBody = new BulletBody(localID);
85 86
86 // Initialize variables kept in base. 87 // Clean out anything that might be in the physical actor list.
87 GravModifier = 1.0f; 88 // Again, a workaround for destroying and recreating an object very quickly.
88 Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); 89 PhysicalActors.Dispose();
89 HoverActive = false;
90
91 // We don't have any physical representation yet.
92 PhysBody = new BulletBody(localID);
93 PhysShape = new BSShapeNull();
94 90
95 UserSetCenterOfMassDisplacement = null; 91 UserSetCenterOfMassDisplacement = null;
96 92
97 PrimAssetState = PrimAssetCondition.Unknown; 93 PrimAssetState = PrimAssetCondition.Unknown;
98 94
95 // Initialize variables kept in base.
96 // Beware that these cause taints to be queued whch can cause race conditions on startup.
97 GravModifier = 1.0f;
98 Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
99 HoverActive = false;
100
99 // Default material type. Also sets Friction, Restitution and Density. 101 // Default material type. Also sets Friction, Restitution and Density.
100 SetMaterial((int)MaterialAttributes.Material.Wood); 102 SetMaterial((int)MaterialAttributes.Material.Wood);
101 103
102 CollisionCollection = new CollisionEventUpdate();
103 CollisionsLastReported = CollisionCollection;
104 CollisionsLastTick = new CollisionEventUpdate();
105 CollisionsLastTickStep = -1; 104 CollisionsLastTickStep = -1;
106 105
107 SubscribedEventsMs = 0; 106 SubscribedEventsMs = 0;
@@ -136,6 +135,15 @@ public abstract class BSPhysObject : PhysicsActor
136 // This mostly prevents property updates and collisions until the object is completely here. 135 // This mostly prevents property updates and collisions until the object is completely here.
137 public bool IsInitialized { get; protected set; } 136 public bool IsInitialized { get; protected set; }
138 137
138 // Set to 'true' if an object (mesh/linkset/sculpty) is not completely constructed.
139 // This test is used to prevent some updates to the object when it only partially exists.
140 // There are several reasons and object might be incomplete:
141 // Its underlying mesh/sculpty is an asset which must be fetched from the asset store
142 // It is a linkset who is being added to or removed from
143 // It is changing state (static to physical, for instance) which requires rebuilding
144 // This is a computed value based on the underlying physical object construction
145 abstract public bool IsIncomplete { get; }
146
139 // Return the object mass without calculating it or having side effects 147 // Return the object mass without calculating it or having side effects
140 public abstract float RawMass { get; } 148 public abstract float RawMass { get; }
141 // Set the raw mass but also update physical mass properties (inertia, ...) 149 // Set the raw mass but also update physical mass properties (inertia, ...)
@@ -148,9 +156,9 @@ public abstract class BSPhysObject : PhysicsActor
148 public OMV.Vector3 Inertia { get; set; } 156 public OMV.Vector3 Inertia { get; set; }
149 157
150 // Reference to the physical body (btCollisionObject) of this object 158 // Reference to the physical body (btCollisionObject) of this object
151 public BulletBody PhysBody; 159 public BulletBody PhysBody = new BulletBody(0);
152 // Reference to the physical shape (btCollisionShape) of this object 160 // Reference to the physical shape (btCollisionShape) of this object
153 public BSShape PhysShape; 161 public BSShape PhysShape = new BSShapeNull();
154 162
155 // The physical representation of the prim might require an asset fetch. 163 // The physical representation of the prim might require an asset fetch.
156 // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'. 164 // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'.
@@ -159,6 +167,11 @@ public abstract class BSPhysObject : PhysicsActor
159 Unknown, Waiting, FailedAssetFetch, FailedMeshing, Fetched 167 Unknown, Waiting, FailedAssetFetch, FailedMeshing, Fetched
160 } 168 }
161 public PrimAssetCondition PrimAssetState { get; set; } 169 public PrimAssetCondition PrimAssetState { get; set; }
170 public virtual bool AssetFailed()
171 {
172 return ( (this.PrimAssetState == PrimAssetCondition.FailedAssetFetch)
173 || (this.PrimAssetState == PrimAssetCondition.FailedMeshing) );
174 }
162 175
163 // The objects base shape information. Null if not a prim type shape. 176 // The objects base shape information. Null if not a prim type shape.
164 public PrimitiveBaseShape BaseShape { get; protected set; } 177 public PrimitiveBaseShape BaseShape { get; protected set; }
@@ -223,7 +236,7 @@ public abstract class BSPhysObject : PhysicsActor
223 public virtual OMV.Quaternion RawOrientation { get; set; } 236 public virtual OMV.Quaternion RawOrientation { get; set; }
224 public abstract OMV.Quaternion ForceOrientation { get; set; } 237 public abstract OMV.Quaternion ForceOrientation { get; set; }
225 238
226 public OMV.Vector3 RawVelocity { get; set; } 239 public virtual OMV.Vector3 RawVelocity { get; set; }
227 public abstract OMV.Vector3 ForceVelocity { get; set; } 240 public abstract OMV.Vector3 ForceVelocity { get; set; }
228 241
229 public OMV.Vector3 RawForce { get; set; } 242 public OMV.Vector3 RawForce { get; set; }
@@ -241,7 +254,12 @@ public abstract class BSPhysObject : PhysicsActor
241 254
242 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } 255 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
243 256
244 public override bool PIDActive { set { MoveToTargetActive = value; } } 257 public override bool PIDActive
258 {
259 get { return MoveToTargetActive; }
260 set { MoveToTargetActive = value; }
261 }
262
245 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } } 263 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } }
246 public override float PIDTau { set { MoveToTargetTau = value; } } 264 public override float PIDTau { set { MoveToTargetTau = value; } }
247 265
@@ -290,11 +308,20 @@ public abstract class BSPhysObject : PhysicsActor
290 // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass. 308 // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass.
291 public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; } 309 public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; }
292 310
293 public OMV.Vector3 LockedLinearAxis { get; set; } // zero means locked. one means free. 311 public OMV.Vector3 LockedLinearAxis; // zero means locked. one means free.
294 public OMV.Vector3 LockedAngularAxis { get; set; } // zero means locked. one means free. 312 public OMV.Vector3 LockedAngularAxis; // zero means locked. one means free.
295 public const float FreeAxis = 1f; 313 public const float FreeAxis = 1f;
314 public const float LockedAxis = 0f;
296 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free 315 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free
297 316
317 // If an axis is locked (flagged above) then the limits of that axis are specified here.
318 // Linear axis limits are relative to the object's starting coordinates.
319 // Angular limits are limited to -PI to +PI
320 public OMV.Vector3 LockedLinearAxisLow;
321 public OMV.Vector3 LockedLinearAxisHigh;
322 public OMV.Vector3 LockedAngularAxisLow;
323 public OMV.Vector3 LockedAngularAxisHigh;
324
298 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so 325 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
299 // they need waking up when parameters are changed. 326 // they need waking up when parameters are changed.
300 // Called in taint-time!! 327 // Called in taint-time!!
@@ -416,12 +443,12 @@ public abstract class BSPhysObject : PhysicsActor
416 } 443 }
417 444
418 // The collisions that have been collected for the next collision reporting (throttled by subscription) 445 // The collisions that have been collected for the next collision reporting (throttled by subscription)
419 protected CollisionEventUpdate CollisionCollection; 446 protected CollisionEventUpdate CollisionCollection = new CollisionEventUpdate();
420 // This is the collision collection last reported to the Simulator. 447 // This is the collision collection last reported to the Simulator.
421 public CollisionEventUpdate CollisionsLastReported; 448 public CollisionEventUpdate CollisionsLastReported = new CollisionEventUpdate();
422 // Remember the collisions recorded in the last tick for fancy collision checking 449 // Remember the collisions recorded in the last tick for fancy collision checking
423 // (like a BSCharacter walking up stairs). 450 // (like a BSCharacter walking up stairs).
424 public CollisionEventUpdate CollisionsLastTick; 451 public CollisionEventUpdate CollisionsLastTick = new CollisionEventUpdate();
425 private long CollisionsLastTickStep = -1; 452 private long CollisionsLastTickStep = -1;
426 453
427 // The simulation step is telling this object about a collision. 454 // The simulation step is telling this object about a collision.
@@ -462,8 +489,11 @@ public abstract class BSPhysObject : PhysicsActor
462 489
463 // If someone has subscribed for collision events log the collision so it will be reported up 490 // If someone has subscribed for collision events log the collision so it will be reported up
464 if (SubscribedEvents()) { 491 if (SubscribedEvents()) {
465 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 492 lock (PhysScene.CollisionLock)
466 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", 493 {
494 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
495 }
496 DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
467 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); 497 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);
468 498
469 ret = true; 499 ret = true;
@@ -474,12 +504,14 @@ public abstract class BSPhysObject : PhysicsActor
474 // Send the collected collisions into the simulator. 504 // Send the collected collisions into the simulator.
475 // Called at taint time from within the Step() function thus no locking problems 505 // Called at taint time from within the Step() function thus no locking problems
476 // with CollisionCollection and ObjectsWithNoMoreCollisions. 506 // with CollisionCollection and ObjectsWithNoMoreCollisions.
507 // Called with BSScene.CollisionLock locked to protect the collision lists.
477 // Return 'true' if there were some actual collisions passed up 508 // Return 'true' if there were some actual collisions passed up
478 public virtual bool SendCollisions() 509 public virtual bool SendCollisions()
479 { 510 {
480 bool ret = true; 511 bool ret = true;
481 512
482 // If the 'no collision' call, force it to happen right now so quick collision_end 513 // If no collisions this call but there were collisions last call, force the collision
514 // event to be happen right now so quick collision_end.
483 bool force = (CollisionCollection.Count == 0 && CollisionsLastReported.Count != 0); 515 bool force = (CollisionCollection.Count == 0 && CollisionsLastReported.Count != 0);
484 516
485 // throttle the collisions to the number of milliseconds specified in the subscription 517 // throttle the collisions to the number of milliseconds specified in the subscription
@@ -562,7 +594,7 @@ public abstract class BSPhysObject : PhysicsActor
562 594
563 #region Per Simulation Step actions 595 #region Per Simulation Step actions
564 596
565 public BSActorCollection PhysicalActors; 597 public BSActorCollection PhysicalActors = new BSActorCollection();
566 598
567 // When an update to the physical properties happens, this event is fired to let 599 // When an update to the physical properties happens, this event is fired to let
568 // different actors to modify the update before it is passed around 600 // different actors to modify the update before it is passed around
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 15b7090..a00991f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -34,6 +34,7 @@ using OMV = OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager; 35using OpenSim.Region.Physics.Manager;
36using OpenSim.Region.Physics.ConvexDecompositionDotNet; 36using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics
37 38
38namespace OpenSim.Region.Physics.BulletSPlugin 39namespace OpenSim.Region.Physics.BulletSPlugin
39{ 40{
@@ -95,11 +96,9 @@ public class BSPrim : BSPhysObject
95 _isPhysical = pisPhysical; 96 _isPhysical = pisPhysical;
96 _isVolumeDetect = false; 97 _isVolumeDetect = false;
97 98
98 // Add a dynamic vehicle to our set of actors that can move this prim.
99 // PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysScene, this, VehicleActorName));
100
101 _mass = CalculateMass(); 99 _mass = CalculateMass();
102 100
101 DetailLog("{0},BSPrim.constructor,pbs={1}", LocalID, BSScene.PrimitiveBaseShapeToString(pbs));
103 // DetailLog("{0},BSPrim.constructor,call", LocalID); 102 // DetailLog("{0},BSPrim.constructor,call", LocalID);
104 // do the actual object creation at taint time 103 // do the actual object creation at taint time
105 PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate() 104 PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate()
@@ -141,6 +140,18 @@ public class BSPrim : BSPhysObject
141 public override bool Stopped { 140 public override bool Stopped {
142 get { return false; } 141 get { return false; }
143 } 142 }
143
144 public override bool IsIncomplete {
145 get {
146 return ShapeRebuildScheduled;
147 }
148 }
149
150 // 'true' if this object's shape is in need of a rebuild and a rebuild has been queued.
151 // The prim is still available but its underlying shape will change soon.
152 // This is protected by a 'lock(this)'.
153 public bool ShapeRebuildScheduled { get; protected set; }
154
144 public override OMV.Vector3 Size { 155 public override OMV.Vector3 Size {
145 get { return _size; } 156 get { return _size; }
146 set { 157 set {
@@ -155,17 +166,42 @@ public class BSPrim : BSPhysObject
155 public override PrimitiveBaseShape Shape { 166 public override PrimitiveBaseShape Shape {
156 set { 167 set {
157 BaseShape = value; 168 BaseShape = value;
169 DetailLog("{0},BSPrim.changeShape,pbs={1}", LocalID, BSScene.PrimitiveBaseShapeToString(BaseShape));
158 PrimAssetState = PrimAssetCondition.Unknown; 170 PrimAssetState = PrimAssetCondition.Unknown;
159 ForceBodyShapeRebuild(false); 171 ForceBodyShapeRebuild(false);
160 } 172 }
161 } 173 }
174 // Cause the body and shape of the prim to be rebuilt if necessary.
175 // If there are no changes required, this is quick and does not make changes to the prim.
176 // If rebuilding is necessary (like changing from static to physical), that will happen.
177 // The 'ShapeRebuildScheduled' tells any checker that the body/shape may change shortly.
178 // The return parameter is not used by anyone.
162 public override bool ForceBodyShapeRebuild(bool inTaintTime) 179 public override bool ForceBodyShapeRebuild(bool inTaintTime)
163 { 180 {
164 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ForceBodyShapeRebuild", delegate() 181 if (inTaintTime)
165 { 182 {
183 // If called in taint time, do the operation immediately
166 _mass = CalculateMass(); // changing the shape changes the mass 184 _mass = CalculateMass(); // changing the shape changes the mass
167 CreateGeomAndObject(true); 185 CreateGeomAndObject(true);
168 }); 186 }
187 else
188 {
189 lock (this)
190 {
191 // If a rebuild is not already in the queue
192 if (!ShapeRebuildScheduled)
193 {
194 // Remember that a rebuild is queued -- this is used to flag an incomplete object
195 ShapeRebuildScheduled = true;
196 PhysScene.TaintedObject(LocalID, "BSPrim.ForceBodyShapeRebuild", delegate()
197 {
198 _mass = CalculateMass(); // changing the shape changes the mass
199 CreateGeomAndObject(true);
200 ShapeRebuildScheduled = false;
201 });
202 }
203 }
204 }
169 return true; 205 return true;
170 } 206 }
171 public override bool Grabbed { 207 public override bool Grabbed {
@@ -249,23 +285,21 @@ public class BSPrim : BSPhysObject
249 { 285 {
250 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 286 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
251 287
252 // "1" means free, "0" means locked 288 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
253 OMV.Vector3 locking = LockedAxisFree; 289 if (axis.X != 1)
254 if (axis.X != 1) locking.X = 0f;
255 if (axis.Y != 1) locking.Y = 0f;
256 if (axis.Z != 1) locking.Z = 0f;
257 LockedAngularAxis = locking;
258
259 EnableActor(LockedAngularAxis != LockedAxisFree, LockedAxisActorName, delegate()
260 { 290 {
261 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); 291 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
262 }); 292 }
263 293 if (axis.Y != 1)
264 // Update parameters so the new actor's Refresh() action is called at the right time.
265 PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate()
266 { 294 {
267 UpdatePhysicalParameters(); 295 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
268 }); 296 }
297 if (axis.Z != 1)
298 {
299 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
300 }
301
302 InitializeAxisActor();
269 303
270 return; 304 return;
271 } 305 }
@@ -376,18 +410,19 @@ public class BSPrim : BSPhysObject
376 { 410 {
377 bool ret = false; 411 bool ret = false;
378 412
379 uint wayOutThere = Constants.RegionSize * Constants.RegionSize; 413 int wayOverThere = -1000;
414 int wayOutThere = 10000;
380 // There have been instances of objects getting thrown way out of bounds and crashing 415 // There have been instances of objects getting thrown way out of bounds and crashing
381 // the border crossing code. 416 // the border crossing code.
382 if ( RawPosition.X < -Constants.RegionSize || RawPosition.X > wayOutThere 417 if ( RawPosition.X < wayOverThere || RawPosition.X > wayOutThere
383 || RawPosition.Y < -Constants.RegionSize || RawPosition.Y > wayOutThere 418 || RawPosition.Y < wayOverThere || RawPosition.X > wayOutThere
384 || RawPosition.Z < -Constants.RegionSize || RawPosition.Z > wayOutThere) 419 || RawPosition.Z < wayOverThere || RawPosition.X > wayOutThere)
385 { 420 {
386 RawPosition = new OMV.Vector3(10, 10, 50); 421 RawPosition = new OMV.Vector3(10, 10, 50);
387 ZeroMotion(inTaintTime); 422 ZeroMotion(inTaintTime);
388 ret = true; 423 ret = true;
389 } 424 }
390 if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocity) 425 if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocitySquared)
391 { 426 {
392 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity); 427 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
393 ret = true; 428 ret = true;
@@ -496,6 +531,12 @@ public class BSPrim : BSPhysObject
496 { 531 {
497 return new BSActorSetForce(PhysScene, this, SetForceActorName); 532 return new BSActorSetForce(PhysScene, this, SetForceActorName);
498 }); 533 });
534
535 // Call update so actor Refresh() is called to start things off
536 PhysScene.TaintedObject(LocalID, "BSPrim.setForce", delegate()
537 {
538 UpdatePhysicalParameters();
539 });
499 } 540 }
500 } 541 }
501 542
@@ -729,6 +770,12 @@ public class BSPrim : BSPhysObject
729 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName); 770 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName);
730 }); 771 });
731 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque); 772 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
773
774 // Call update so actor Refresh() is called to start things off
775 PhysScene.TaintedObject(LocalID, "BSPrim.setTorque", delegate()
776 {
777 UpdatePhysicalParameters();
778 });
732 } 779 }
733 } 780 }
734 public override OMV.Vector3 Acceleration { 781 public override OMV.Vector3 Acceleration {
@@ -1086,13 +1133,27 @@ public class BSPrim : BSPhysObject
1086 } 1133 }
1087 } 1134 }
1088 1135
1089 public override bool PIDActive { 1136 public override bool PIDActive
1090 set { 1137 {
1091 base.MoveToTargetActive = value; 1138 get
1139 {
1140 return MoveToTargetActive;
1141 }
1142
1143 set
1144 {
1145 MoveToTargetActive = value;
1146
1092 EnableActor(MoveToTargetActive, MoveToTargetActorName, delegate() 1147 EnableActor(MoveToTargetActive, MoveToTargetActorName, delegate()
1093 { 1148 {
1094 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName); 1149 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName);
1095 }); 1150 });
1151
1152 // Call update so actor Refresh() is called to start things off
1153 PhysScene.TaintedObject(LocalID, "BSPrim.PIDActive", delegate()
1154 {
1155 UpdatePhysicalParameters();
1156 });
1096 } 1157 }
1097 } 1158 }
1098 1159
@@ -1119,6 +1180,12 @@ public class BSPrim : BSPhysObject
1119 { 1180 {
1120 return new BSActorHover(PhysScene, this, HoverActorName); 1181 return new BSActorHover(PhysScene, this, HoverActorName);
1121 }); 1182 });
1183
1184 // Call update so actor Refresh() is called to start things off
1185 PhysScene.TaintedObject(LocalID, "BSPrim.PIDHoverActive", delegate()
1186 {
1187 UpdatePhysicalParameters();
1188 });
1122 } 1189 }
1123 } 1190 }
1124 1191
@@ -1556,12 +1623,232 @@ public class BSPrim : BSPhysObject
1556 object ret = null; 1623 object ret = null;
1557 switch (pFunct) 1624 switch (pFunct)
1558 { 1625 {
1626 case ExtendedPhysics.PhysFunctAxisLockLimits:
1627 ret = SetAxisLockLimitsExtension(pParams);
1628 break;
1559 default: 1629 default:
1560 ret = base.Extension(pFunct, pParams); 1630 ret = base.Extension(pFunct, pParams);
1561 break; 1631 break;
1562 } 1632 }
1563 return ret; 1633 return ret;
1564 } 1634 }
1635
1636 private void InitializeAxisActor()
1637 {
1638 EnableActor(LockedAngularAxis != LockedAxisFree || LockedLinearAxis != LockedAxisFree,
1639 LockedAxisActorName, delegate()
1640 {
1641 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName);
1642 });
1643
1644 // Update parameters so the new actor's Refresh() action is called at the right time.
1645 PhysScene.TaintedObject(LocalID, "BSPrim.LockAxis", delegate()
1646 {
1647 UpdatePhysicalParameters();
1648 });
1649 }
1650
1651 // Passed an array of an array of parameters, set the axis locking.
1652 // This expects an int (PHYS_AXIS_*) followed by none or two limit floats
1653 // followed by another int and floats, etc.
1654 private object SetAxisLockLimitsExtension(object[] pParams)
1655 {
1656 DetailLog("{0} SetAxisLockLimitsExtension. parmlen={1}", LocalID, pParams.GetLength(0));
1657 object ret = null;
1658 try
1659 {
1660 if (pParams.GetLength(0) > 1)
1661 {
1662 int index = 2;
1663 while (index < pParams.GetLength(0))
1664 {
1665 var funct = pParams[index];
1666 DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index);
1667 if (funct is Int32 || funct is Int64)
1668 {
1669 switch ((int)funct)
1670 {
1671 // Those that take no parameters
1672 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
1673 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
1674 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
1675 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
1676 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
1677 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
1678 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
1679 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
1680 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
1681 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
1682 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
1683 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
1684 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
1685 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
1686 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
1687 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
1688 case ExtendedPhysics.PHYS_AXIS_UNLOCK:
1689 ApplyAxisLimits((int)funct, 0f, 0f);
1690 index += 1;
1691 break;
1692 // Those that take two parameters (the limits)
1693 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
1694 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
1695 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
1696 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
1697 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
1698 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
1699 ApplyAxisLimits((int)funct, (float)pParams[index + 1], (float)pParams[index + 2]);
1700 index += 3;
1701 break;
1702 default:
1703 m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct);
1704 index += 1;
1705 break;
1706 }
1707 }
1708 }
1709 InitializeAxisActor();
1710 ret = (object)index;
1711 }
1712 }
1713 catch (Exception e)
1714 {
1715 m_log.WarnFormat("{0} SetSxisLockLimitsExtension exception in object {1}: {2}", LogHeader, this.Name, e);
1716 ret = null;
1717 }
1718 return ret; // not implemented yet
1719 }
1720
1721 // Set the locking parameters.
1722 // If an axis is locked, the limits for the axis are set to zero,
1723 // If the axis is being constrained, the high and low value are passed and set.
1724 // When done here, LockedXXXAxis flags are set and LockedXXXAxixLow/High are set to the range.
1725 protected void ApplyAxisLimits(int funct, float low, float high)
1726 {
1727 DetailLog("{0} ApplyAxisLimits. op={1}, low={2}, high={3}", LocalID, funct, low, high);
1728 float linearMax = 23000f;
1729 float angularMax = (float)Math.PI;
1730
1731 switch (funct)
1732 {
1733 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
1734 this.LockedLinearAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
1735 this.LockedLinearAxisLow = OMV.Vector3.Zero;
1736 this.LockedLinearAxisHigh = OMV.Vector3.Zero;
1737 break;
1738 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
1739 this.LockedLinearAxis.X = LockedAxis;
1740 this.LockedLinearAxisLow.X = 0f;
1741 this.LockedLinearAxisHigh.X = 0f;
1742 break;
1743 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
1744 this.LockedLinearAxis.X = LockedAxis;
1745 this.LockedLinearAxisLow.X = Util.Clip(low, -linearMax, linearMax);
1746 this.LockedLinearAxisHigh.X = Util.Clip(high, -linearMax, linearMax);
1747 break;
1748 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
1749 this.LockedLinearAxis.Y = LockedAxis;
1750 this.LockedLinearAxisLow.Y = 0f;
1751 this.LockedLinearAxisHigh.Y = 0f;
1752 break;
1753 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
1754 this.LockedLinearAxis.Y = LockedAxis;
1755 this.LockedLinearAxisLow.Y = Util.Clip(low, -linearMax, linearMax);
1756 this.LockedLinearAxisHigh.Y = Util.Clip(high, -linearMax, linearMax);
1757 break;
1758 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
1759 this.LockedLinearAxis.Z = LockedAxis;
1760 this.LockedLinearAxisLow.Z = 0f;
1761 this.LockedLinearAxisHigh.Z = 0f;
1762 break;
1763 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
1764 this.LockedLinearAxis.Z = LockedAxis;
1765 this.LockedLinearAxisLow.Z = Util.Clip(low, -linearMax, linearMax);
1766 this.LockedLinearAxisHigh.Z = Util.Clip(high, -linearMax, linearMax);
1767 break;
1768 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
1769 this.LockedAngularAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
1770 this.LockedAngularAxisLow = OMV.Vector3.Zero;
1771 this.LockedAngularAxisHigh = OMV.Vector3.Zero;
1772 break;
1773 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
1774 this.LockedAngularAxis.X = LockedAxis;
1775 this.LockedAngularAxisLow.X = 0;
1776 this.LockedAngularAxisHigh.X = 0;
1777 break;
1778 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
1779 this.LockedAngularAxis.X = LockedAxis;
1780 this.LockedAngularAxisLow.X = Util.Clip(low, -angularMax, angularMax);
1781 this.LockedAngularAxisHigh.X = Util.Clip(high, -angularMax, angularMax);
1782 break;
1783 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
1784 this.LockedAngularAxis.Y = LockedAxis;
1785 this.LockedAngularAxisLow.Y = 0;
1786 this.LockedAngularAxisHigh.Y = 0;
1787 break;
1788 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
1789 this.LockedAngularAxis.Y = LockedAxis;
1790 this.LockedAngularAxisLow.Y = Util.Clip(low, -angularMax, angularMax);
1791 this.LockedAngularAxisHigh.Y = Util.Clip(high, -angularMax, angularMax);
1792 break;
1793 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
1794 this.LockedAngularAxis.Z = LockedAxis;
1795 this.LockedAngularAxisLow.Z = 0;
1796 this.LockedAngularAxisHigh.Z = 0;
1797 break;
1798 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
1799 this.LockedAngularAxis.Z = LockedAxis;
1800 this.LockedAngularAxisLow.Z = Util.Clip(low, -angularMax, angularMax);
1801 this.LockedAngularAxisHigh.Z = Util.Clip(high, -angularMax, angularMax);
1802 break;
1803 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
1804 this.LockedLinearAxis = LockedAxisFree;
1805 this.LockedLinearAxisLow = new OMV.Vector3(-linearMax, -linearMax, -linearMax);
1806 this.LockedLinearAxisHigh = new OMV.Vector3(linearMax, linearMax, linearMax);
1807 break;
1808 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
1809 this.LockedLinearAxis.X = FreeAxis;
1810 this.LockedLinearAxisLow.X = -linearMax;
1811 this.LockedLinearAxisHigh.X = linearMax;
1812 break;
1813 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
1814 this.LockedLinearAxis.Y = FreeAxis;
1815 this.LockedLinearAxisLow.Y = -linearMax;
1816 this.LockedLinearAxisHigh.Y = linearMax;
1817 break;
1818 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
1819 this.LockedLinearAxis.Z = FreeAxis;
1820 this.LockedLinearAxisLow.Z = -linearMax;
1821 this.LockedLinearAxisHigh.Z = linearMax;
1822 break;
1823 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
1824 this.LockedAngularAxis = LockedAxisFree;
1825 this.LockedAngularAxisLow = new OMV.Vector3(-angularMax, -angularMax, -angularMax);
1826 this.LockedAngularAxisHigh = new OMV.Vector3(angularMax, angularMax, angularMax);
1827 break;
1828 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
1829 this.LockedAngularAxis.X = FreeAxis;
1830 this.LockedAngularAxisLow.X = -angularMax;
1831 this.LockedAngularAxisHigh.X = angularMax;
1832 break;
1833 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
1834 this.LockedAngularAxis.Y = FreeAxis;
1835 this.LockedAngularAxisLow.Y = -angularMax;
1836 this.LockedAngularAxisHigh.Y = angularMax;
1837 break;
1838 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
1839 this.LockedAngularAxis.Z = FreeAxis;
1840 this.LockedAngularAxisLow.Z = -angularMax;
1841 this.LockedAngularAxisHigh.Z = angularMax;
1842 break;
1843 case ExtendedPhysics.PHYS_AXIS_UNLOCK:
1844 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
1845 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
1846 break;
1847 default:
1848 break;
1849 }
1850 return;
1851 }
1565 #endregion // Extension 1852 #endregion // Extension
1566 1853
1567 // The physics engine says that properties have updated. Update same and inform 1854 // The physics engine says that properties have updated. Update same and inform
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index 126b146..430d645 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -42,7 +42,9 @@ public class BSPrimLinkable : BSPrimDisplaced
42 // operations necessary for keeping the linkset created and, additionally, this 42 // operations necessary for keeping the linkset created and, additionally, this
43 // calls the linkset implementation for its creation and management. 43 // calls the linkset implementation for its creation and management.
44 44
45#pragma warning disable 414
45 private static readonly string LogHeader = "[BULLETS PRIMLINKABLE]"; 46 private static readonly string LogHeader = "[BULLETS PRIMLINKABLE]";
47#pragma warning restore 414
46 48
47 // This adds the overrides for link() and delink() so the prim is linkable. 49 // This adds the overrides for link() and delink() so the prim is linkable.
48 50
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index b3dfa41..8a19944 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -32,6 +32,7 @@ using System.Runtime.InteropServices;
32using System.Text; 32using System.Text;
33using System.Threading; 33using System.Threading;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Monitoring;
35using OpenSim.Region.Framework; 36using OpenSim.Region.Framework;
36using OpenSim.Region.CoreModules; 37using OpenSim.Region.CoreModules;
37using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging; 38using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging;
@@ -75,7 +76,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
75 76
76 // Keep track of all the avatars so we can send them a collision event 77 // Keep track of all the avatars so we can send them a collision event
77 // every tick so OpenSim will update its animation. 78 // every tick so OpenSim will update its animation.
78 private HashSet<BSPhysObject> m_avatars = new HashSet<BSPhysObject>(); 79 private HashSet<BSPhysObject> AvatarsInScene = new HashSet<BSPhysObject>();
80 private Object AvatarsInSceneLock = new Object();
79 81
80 // let my minuions use my logger 82 // let my minuions use my logger
81 public ILog Logger { get { return m_log; } } 83 public ILog Logger { get { return m_log; } }
@@ -88,7 +90,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
88 public BSConstraintCollection Constraints { get; private set; } 90 public BSConstraintCollection Constraints { get; private set; }
89 91
90 // Simulation parameters 92 // Simulation parameters
91 internal float m_physicsStepTime; // if running independently, the interval simulated by default 93 //internal float m_physicsStepTime; // if running independently, the interval simulated by default
92 94
93 internal int m_maxSubSteps; 95 internal int m_maxSubSteps;
94 internal float m_fixedTimeStep; 96 internal float m_fixedTimeStep;
@@ -129,6 +131,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
129 internal int m_maxUpdatesPerFrame; 131 internal int m_maxUpdatesPerFrame;
130 internal EntityProperties[] m_updateArray; 132 internal EntityProperties[] m_updateArray;
131 133
134 /// <summary>
135 /// Used to control physics simulation timing if Bullet is running on its own thread.
136 /// </summary>
137 private ManualResetEvent m_updateWaitEvent;
138
132 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 139 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
133 public const uint GROUNDPLANE_ID = 1; 140 public const uint GROUNDPLANE_ID = 1;
134 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here 141 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
@@ -208,8 +215,17 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
208 Name = EngineType + "/" + RegionName; 215 Name = EngineType + "/" + RegionName;
209 } 216 }
210 217
218 // Old version of initialization that assumes legacy sized regions (256x256)
211 public override void Initialise(IMesher meshmerizer, IConfigSource config) 219 public override void Initialise(IMesher meshmerizer, IConfigSource config)
212 { 220 {
221 m_log.ErrorFormat("{0} WARNING WARNING WARNING! BulletSim initialized without region extent specification. Terrain will be messed up.");
222 Vector3 regionExtent = new Vector3( Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
223 Initialise(meshmerizer, config, regionExtent);
224
225 }
226
227 public override void Initialise(IMesher meshmerizer, IConfigSource config, Vector3 regionExtent)
228 {
213 mesher = meshmerizer; 229 mesher = meshmerizer;
214 _taintOperations = new List<TaintCallbackEntry>(); 230 _taintOperations = new List<TaintCallbackEntry>();
215 _postTaintOperations = new Dictionary<string, TaintCallbackEntry>(); 231 _postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
@@ -226,6 +242,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
226 // Set default values for physics parameters plus any overrides from the ini file 242 // Set default values for physics parameters plus any overrides from the ini file
227 GetInitialParameterValues(config); 243 GetInitialParameterValues(config);
228 244
245 // Force some parameters to values depending on other configurations
246 // Only use heightmap terrain implementation if terrain larger than legacy size
247 if ((uint)regionExtent.X > Constants.RegionSize || (uint)regionExtent.Y > Constants.RegionSize)
248 {
249 m_log.WarnFormat("{0} Forcing terrain implementation to heightmap for large region", LogHeader);
250 BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
251 }
252
229 // Get the connection to the physics engine (could be native or one of many DLLs) 253 // Get the connection to the physics engine (could be native or one of many DLLs)
230 PE = SelectUnderlyingBulletEngine(BulletEngineName); 254 PE = SelectUnderlyingBulletEngine(BulletEngineName);
231 255
@@ -250,13 +274,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
250 // a child in a mega-region. 274 // a child in a mega-region.
251 // Bullet actually doesn't care about the extents of the simulated 275 // Bullet actually doesn't care about the extents of the simulated
252 // area. It tracks active objects no matter where they are. 276 // area. It tracks active objects no matter where they are.
253 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 277 Vector3 worldExtent = regionExtent;
254 278
255 World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray); 279 World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray);
256 280
257 Constraints = new BSConstraintCollection(World); 281 Constraints = new BSConstraintCollection(World);
258 282
259 TerrainManager = new BSTerrainManager(this); 283 TerrainManager = new BSTerrainManager(this, worldExtent);
260 TerrainManager.CreateInitialGroundPlaneAndTerrain(); 284 TerrainManager.CreateInitialGroundPlaneAndTerrain();
261 285
262 // Put some informational messages into the log file. 286 // Put some informational messages into the log file.
@@ -269,9 +293,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
269 if (BSParam.UseSeparatePhysicsThread) 293 if (BSParam.UseSeparatePhysicsThread)
270 { 294 {
271 // The physics simulation should happen independently of the heartbeat loop 295 // The physics simulation should happen independently of the heartbeat loop
272 m_physicsThread = new Thread(BulletSPluginPhysicsThread); 296 m_physicsThread
273 m_physicsThread.Name = BulletEngineName; 297 = WorkManager.StartThread(
274 m_physicsThread.Start(); 298 BulletSPluginPhysicsThread,
299 string.Format("{0} ({1})", BulletEngineName, RegionName),
300 ThreadPriority.Normal,
301 true,
302 true);
275 } 303 }
276 } 304 }
277 305
@@ -381,7 +409,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
381 409
382 if (ret == null) 410 if (ret == null)
383 { 411 {
384 m_log.ErrorFormat("{0) COULD NOT SELECT BULLET ENGINE: '[BulletSim]PhysicsEngine' must be either 'BulletUnmanaged-*' or 'BulletXNA-*'", LogHeader); 412 m_log.ErrorFormat("{0} COULD NOT SELECT BULLET ENGINE: '[BulletSim]PhysicsEngine' must be either 'BulletUnmanaged-*' or 'BulletXNA-*'", LogHeader);
385 } 413 }
386 else 414 else
387 { 415 {
@@ -398,11 +426,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
398 // make sure no stepping happens while we're deleting stuff 426 // make sure no stepping happens while we're deleting stuff
399 m_initialized = false; 427 m_initialized = false;
400 428
401 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects) 429 lock (PhysObjects)
402 { 430 {
403 kvp.Value.Destroy(); 431 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
432 {
433 kvp.Value.Destroy();
434 }
435 PhysObjects.Clear();
404 } 436 }
405 PhysObjects.Clear();
406 437
407 // Now that the prims are all cleaned up, there should be no constraints left 438 // Now that the prims are all cleaned up, there should be no constraints left
408 if (Constraints != null) 439 if (Constraints != null)
@@ -434,27 +465,27 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
434 465
435 #region Prim and Avatar addition and removal 466 #region Prim and Avatar addition and removal
436 467
437 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 468 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
438 { 469 {
439 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); 470 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
440 return null; 471 return null;
441 } 472 }
442 473
443 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) 474 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
444 { 475 {
445 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); 476 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
446 477
447 if (!m_initialized) return null; 478 if (!m_initialized) return null;
448 479
449 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 480 BSCharacter actor = new BSCharacter(localID, avName, this, position, velocity, size, isFlying);
450 lock (PhysObjects) 481 lock (PhysObjects)
451 PhysObjects.Add(localID, actor); 482 PhysObjects.Add(localID, actor);
452 483
453 // TODO: Remove kludge someday. 484 // TODO: Remove kludge someday.
454 // We must generate a collision for avatars whether they collide or not. 485 // We must generate a collision for avatars whether they collide or not.
455 // This is required by OpenSim to update avatar animations, etc. 486 // This is required by OpenSim to update avatar animations, etc.
456 lock (m_avatars) 487 lock (AvatarsInSceneLock)
457 m_avatars.Add(actor); 488 AvatarsInScene.Add(actor);
458 489
459 return actor; 490 return actor;
460 } 491 }
@@ -473,8 +504,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
473 lock (PhysObjects) 504 lock (PhysObjects)
474 PhysObjects.Remove(bsactor.LocalID); 505 PhysObjects.Remove(bsactor.LocalID);
475 // Remove kludge someday 506 // Remove kludge someday
476 lock (m_avatars) 507 lock (AvatarsInSceneLock)
477 m_avatars.Remove(bsactor); 508 AvatarsInScene.Remove(bsactor);
478 } 509 }
479 catch (Exception e) 510 catch (Exception e)
480 { 511 {
@@ -622,15 +653,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
622 { 653 {
623 if (collidersCount > 0) 654 if (collidersCount > 0)
624 { 655 {
625 for (int ii = 0; ii < collidersCount; ii++) 656 lock (PhysObjects)
626 { 657 {
627 uint cA = m_collisionArray[ii].aID; 658 for (int ii = 0; ii < collidersCount; ii++)
628 uint cB = m_collisionArray[ii].bID; 659 {
629 Vector3 point = m_collisionArray[ii].point; 660 uint cA = m_collisionArray[ii].aID;
630 Vector3 normal = m_collisionArray[ii].normal; 661 uint cB = m_collisionArray[ii].bID;
631 float penetration = m_collisionArray[ii].penetration; 662 Vector3 point = m_collisionArray[ii].point;
632 SendCollision(cA, cB, point, normal, penetration); 663 Vector3 normal = m_collisionArray[ii].normal;
633 SendCollision(cB, cA, point, -normal, penetration); 664 float penetration = m_collisionArray[ii].penetration;
665 SendCollision(cA, cB, point, normal, penetration);
666 SendCollision(cB, cA, point, -normal, penetration);
667 }
634 } 668 }
635 } 669 }
636 } 670 }
@@ -641,14 +675,17 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
641 { 675 {
642 if (updatedEntityCount > 0) 676 if (updatedEntityCount > 0)
643 { 677 {
644 for (int ii = 0; ii < updatedEntityCount; ii++) 678 lock (PhysObjects)
645 { 679 {
646 EntityProperties entprop = m_updateArray[ii]; 680 for (int ii = 0; ii < updatedEntityCount; ii++)
647 BSPhysObject pobj;
648 if (PhysObjects.TryGetValue(entprop.ID, out pobj))
649 { 681 {
650 if (pobj.IsInitialized) 682 EntityProperties entprop = m_updateArray[ii];
651 pobj.UpdateProperties(entprop); 683 BSPhysObject pobj;
684 if (PhysObjects.TryGetValue(entprop.ID, out pobj))
685 {
686 if (pobj.IsInitialized)
687 pobj.UpdateProperties(entprop);
688 }
652 } 689 }
653 } 690 }
654 } 691 }
@@ -682,7 +719,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
682 // this is is under UpdateLock. 719 // this is is under UpdateLock.
683 public void PostUpdate(BSPhysObject updatee) 720 public void PostUpdate(BSPhysObject updatee)
684 { 721 {
685 ObjectsWithUpdates.Add(updatee); 722 lock (UpdateLock)
723 {
724 ObjectsWithUpdates.Add(updatee);
725 }
686 } 726 }
687 727
688 // The simulator thinks it is physics time so return all the collisions and position 728 // The simulator thinks it is physics time so return all the collisions and position
@@ -710,9 +750,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
710 // The simulator expects collisions for avatars even if there are have been no collisions. 750 // The simulator expects collisions for avatars even if there are have been no collisions.
711 // The event updates avatar animations and stuff. 751 // The event updates avatar animations and stuff.
712 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. 752 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
713 foreach (BSPhysObject bsp in m_avatars) 753 // Note that we get a copy of the list to search because SendCollision() can take a while.
714 if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice 754 HashSet<BSPhysObject> tempAvatarsInScene;
715 bsp.SendCollisions(); 755 lock (AvatarsInSceneLock)
756 {
757 tempAvatarsInScene = new HashSet<BSPhysObject>(AvatarsInScene);
758 }
759 foreach (BSPhysObject actor in tempAvatarsInScene)
760 {
761 if (!ObjectsWithCollisions.Contains(actor)) // don't call avatars twice
762 actor.SendCollisions();
763 }
764 tempAvatarsInScene = null;
716 765
717 // Objects that are done colliding are removed from the ObjectsWithCollisions list. 766 // Objects that are done colliding are removed from the ObjectsWithCollisions list.
718 // Not done above because it is inside an iteration of ObjectWithCollisions. 767 // Not done above because it is inside an iteration of ObjectWithCollisions.
@@ -762,6 +811,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
762 } 811 }
763 812
764 BSPhysObject collider; 813 BSPhysObject collider;
814 // NOTE that PhysObjects was locked before the call to SendCollision().
765 if (!PhysObjects.TryGetValue(localID, out collider)) 815 if (!PhysObjects.TryGetValue(localID, out collider))
766 { 816 {
767 // If the object that is colliding cannot be found, just ignore the collision. 817 // If the object that is colliding cannot be found, just ignore the collision.
@@ -780,7 +830,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
780 if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) 830 if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
781 { 831 {
782 // If a collision was 'good', remember to send it to the simulator 832 // If a collision was 'good', remember to send it to the simulator
783 ObjectsWithCollisions.Add(collider); 833 lock (CollisionLock)
834 {
835 ObjectsWithCollisions.Add(collider);
836 }
784 } 837 }
785 } 838 }
786 839
@@ -789,18 +842,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
789 842
790 public void BulletSPluginPhysicsThread() 843 public void BulletSPluginPhysicsThread()
791 { 844 {
845 Thread.CurrentThread.Priority = ThreadPriority.Highest;
846 m_updateWaitEvent = new ManualResetEvent(false);
847
792 while (m_initialized) 848 while (m_initialized)
793 { 849 {
794 int beginSimulationRealtimeMS = Util.EnvironmentTickCount(); 850 int beginSimulationRealtimeMS = Util.EnvironmentTickCount();
795 DoPhysicsStep(BSParam.PhysicsTimeStep); 851
852 if (BSParam.Active)
853 DoPhysicsStep(BSParam.PhysicsTimeStep);
854
796 int simulationRealtimeMS = Util.EnvironmentTickCountSubtract(beginSimulationRealtimeMS); 855 int simulationRealtimeMS = Util.EnvironmentTickCountSubtract(beginSimulationRealtimeMS);
797 int simulationTimeVsRealtimeDifferenceMS = ((int)(BSParam.PhysicsTimeStep*1000f)) - simulationRealtimeMS; 856 int simulationTimeVsRealtimeDifferenceMS = ((int)(BSParam.PhysicsTimeStep*1000f)) - simulationRealtimeMS;
798 857
799 if (simulationTimeVsRealtimeDifferenceMS > 0) 858 if (simulationTimeVsRealtimeDifferenceMS > 0)
800 { 859 {
801 // The simulation of the time interval took less than realtime. 860 // The simulation of the time interval took less than realtime.
802 // Do a sleep for the rest of realtime. 861 // Do a wait for the rest of realtime.
803 Thread.Sleep(simulationTimeVsRealtimeDifferenceMS); 862 m_updateWaitEvent.WaitOne(simulationTimeVsRealtimeDifferenceMS);
863 //Thread.Sleep(simulationTimeVsRealtimeDifferenceMS);
804 } 864 }
805 else 865 else
806 { 866 {
@@ -809,7 +869,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
809 // TODO. 869 // TODO.
810 DetailLog("{0},BulletSPluginPhysicsThread,longerThanRealtime={1}", BSScene.DetailLogZero, simulationTimeVsRealtimeDifferenceMS); 870 DetailLog("{0},BulletSPluginPhysicsThread,longerThanRealtime={1}", BSScene.DetailLogZero, simulationTimeVsRealtimeDifferenceMS);
811 } 871 }
872
873 Watchdog.UpdateThread();
812 } 874 }
875
876 Watchdog.RemoveThread();
813 } 877 }
814 878
815 #endregion // Simulation 879 #endregion // Simulation
@@ -882,6 +946,75 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
882 } 946 }
883 #endregion // Extensions 947 #endregion // Extensions
884 948
949 public static string PrimitiveBaseShapeToString(PrimitiveBaseShape pbs)
950 {
951 float pathShearX = pbs.PathShearX < 128 ? (float)pbs.PathShearX * 0.01f : (float)(pbs.PathShearX - 256) * 0.01f;
952 float pathShearY = pbs.PathShearY < 128 ? (float)pbs.PathShearY * 0.01f : (float)(pbs.PathShearY - 256) * 0.01f;
953 float pathBegin = (float)pbs.PathBegin * 2.0e-5f;
954 float pathEnd = 1.0f - (float)pbs.PathEnd * 2.0e-5f;
955 float pathScaleX = (float)(200 - pbs.PathScaleX) * 0.01f;
956 float pathScaleY = (float)(200 - pbs.PathScaleY) * 0.01f;
957 float pathTaperX = pbs.PathTaperX * 0.01f;
958 float pathTaperY = pbs.PathTaperY * 0.01f;
959
960 float profileBegin = (float)pbs.ProfileBegin * 2.0e-5f;
961 float profileEnd = 1.0f - (float)pbs.ProfileEnd * 2.0e-5f;
962 float profileHollow = (float)pbs.ProfileHollow * 2.0e-5f;
963 if (profileHollow > 0.95f)
964 profileHollow = 0.95f;
965
966 StringBuilder buff = new StringBuilder();
967 buff.Append("shape=");
968 buff.Append(((ProfileShape)pbs.ProfileShape).ToString());
969 buff.Append(",");
970 buff.Append("hollow=");
971 buff.Append(((HollowShape)pbs.HollowShape).ToString());
972 buff.Append(",");
973 buff.Append("pathCurve=");
974 buff.Append(((Extrusion)pbs.PathCurve).ToString());
975 buff.Append(",");
976 buff.Append("profCurve=");
977 buff.Append(((Extrusion)pbs.ProfileCurve).ToString());
978 buff.Append(",");
979 buff.Append("profHollow=");
980 buff.Append(profileHollow.ToString());
981 buff.Append(",");
982 buff.Append("pathBegEnd=");
983 buff.Append(pathBegin.ToString());
984 buff.Append("/");
985 buff.Append(pathEnd.ToString());
986 buff.Append(",");
987 buff.Append("profileBegEnd=");
988 buff.Append(profileBegin.ToString());
989 buff.Append("/");
990 buff.Append(profileEnd.ToString());
991 buff.Append(",");
992 buff.Append("scaleXY=");
993 buff.Append(pathScaleX.ToString());
994 buff.Append("/");
995 buff.Append(pathScaleY.ToString());
996 buff.Append(",");
997 buff.Append("shearXY=");
998 buff.Append(pathShearX.ToString());
999 buff.Append("/");
1000 buff.Append(pathShearY.ToString());
1001 buff.Append(",");
1002 buff.Append("taperXY=");
1003 buff.Append(pbs.PathTaperX.ToString());
1004 buff.Append("/");
1005 buff.Append(pbs.PathTaperY.ToString());
1006 buff.Append(",");
1007 buff.Append("skew=");
1008 buff.Append(pbs.PathSkew.ToString());
1009 buff.Append(",");
1010 buff.Append("twist/Beg=");
1011 buff.Append(pbs.PathTwist.ToString());
1012 buff.Append("/");
1013 buff.Append(pbs.PathTwistBegin.ToString());
1014
1015 return buff.ToString();
1016 }
1017
885 #region Taints 1018 #region Taints
886 // The simulation execution order is: 1019 // The simulation execution order is:
887 // Simulate() 1020 // Simulate()
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 32bbc8f..d1de844 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -36,7 +36,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public sealed class BSShapeCollection : IDisposable 37public sealed class BSShapeCollection : IDisposable
38{ 38{
39#pragma warning disable 414
39 private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]"; 40 private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]";
41#pragma warning restore 414
40 42
41 private BSScene m_physicsScene { get; set; } 43 private BSScene m_physicsScene { get; set; }
42 44
@@ -124,6 +126,10 @@ public sealed class BSShapeCollection : IDisposable
124 // Info in prim.BSShape is updated to the new shape. 126 // Info in prim.BSShape is updated to the new shape.
125 // Returns 'true' if the geometry was rebuilt. 127 // Returns 'true' if the geometry was rebuilt.
126 // Called at taint-time! 128 // Called at taint-time!
129 public const int AvatarShapeCapsule = 0;
130 public const int AvatarShapeCube = 1;
131 public const int AvatarShapeOvoid = 2;
132 public const int AvatarShapeMesh = 3;
127 private bool CreateGeom(bool forceRebuild, BSPhysObject prim, PhysicalDestructionCallback shapeCallback) 133 private bool CreateGeom(bool forceRebuild, BSPhysObject prim, PhysicalDestructionCallback shapeCallback)
128 { 134 {
129 bool ret = false; 135 bool ret = false;
@@ -137,10 +143,32 @@ public sealed class BSShapeCollection : IDisposable
137 if (theChar != null) 143 if (theChar != null)
138 { 144 {
139 DereferenceExistingShape(prim, shapeCallback); 145 DereferenceExistingShape(prim, shapeCallback);
140 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim, 146 switch (BSParam.AvatarShape)
147 {
148 case AvatarShapeCapsule:
149 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
141 BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE); 150 BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE);
142 ret = true; 151 ret = true;
143 haveShape = true; 152 haveShape = true;
153 break;
154 case AvatarShapeCube:
155 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
156 BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_CAPSULE);
157 ret = true;
158 haveShape = true;
159 break;
160 case AvatarShapeOvoid:
161 // Saddly, Bullet doesn't scale spheres so this doesn't work as an avatar shape
162 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
163 BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_CAPSULE);
164 ret = true;
165 haveShape = true;
166 break;
167 case AvatarShapeMesh:
168 break;
169 default:
170 break;
171 }
144 } 172 }
145 173
146 // If the prim attributes are simple, this could be a simple Bullet native shape 174 // If the prim attributes are simple, this could be a simple Bullet native shape
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index fe5ff6c..03a9ddc 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -38,6 +38,76 @@ using OMV = OpenMetaverse;
38 38
39namespace OpenSim.Region.Physics.BulletSPlugin 39namespace OpenSim.Region.Physics.BulletSPlugin
40{ 40{
41// Information class that holds stats for the shape. Which values mean
42// something depends on the type of shape.
43// This information is used for debugging and stats and is not used
44// for operational things.
45public class ShapeInfoInfo
46{
47 public int Vertices { get; set; }
48 private int m_hullCount;
49 private int[] m_verticesPerHull;
50 public ShapeInfoInfo()
51 {
52 Vertices = 0;
53 m_hullCount = 0;
54 m_verticesPerHull = null;
55 }
56 public int HullCount
57 {
58 set
59 {
60 m_hullCount = value;
61 m_verticesPerHull = new int[m_hullCount];
62 Array.Clear(m_verticesPerHull, 0, m_hullCount);
63 }
64 get { return m_hullCount; }
65 }
66 public void SetVerticesPerHull(int hullNum, int vertices)
67 {
68 if (m_verticesPerHull != null && hullNum < m_verticesPerHull.Length)
69 {
70 m_verticesPerHull[hullNum] = vertices;
71 }
72 }
73 public int GetVerticesPerHull(int hullNum)
74 {
75 if (m_verticesPerHull != null && hullNum < m_verticesPerHull.Length)
76 {
77 return m_verticesPerHull[hullNum];
78 }
79 return 0;
80 }
81 public override string ToString()
82 {
83 StringBuilder buff = new StringBuilder();
84 // buff.Append("ShapeInfo=<");
85 buff.Append("<");
86 if (Vertices > 0)
87 {
88 buff.Append("verts=");
89 buff.Append(Vertices.ToString());
90 }
91
92 if (Vertices > 0 && HullCount > 0) buff.Append(",");
93
94 if (HullCount > 0)
95 {
96 buff.Append("nHulls=");
97 buff.Append(HullCount.ToString());
98 buff.Append(",");
99 buff.Append("hullVerts=");
100 for (int ii = 0; ii < HullCount; ii++)
101 {
102 if (ii != 0) buff.Append(",");
103 buff.Append(GetVerticesPerHull(ii).ToString());
104 }
105 }
106 buff.Append(">");
107 return buff.ToString();
108 }
109}
110
41public abstract class BSShape 111public abstract class BSShape
42{ 112{
43 private static string LogHeader = "[BULLETSIM SHAPE]"; 113 private static string LogHeader = "[BULLETSIM SHAPE]";
@@ -45,18 +115,21 @@ public abstract class BSShape
45 public int referenceCount { get; set; } 115 public int referenceCount { get; set; }
46 public DateTime lastReferenced { get; set; } 116 public DateTime lastReferenced { get; set; }
47 public BulletShape physShapeInfo { get; set; } 117 public BulletShape physShapeInfo { get; set; }
118 public ShapeInfoInfo shapeInfo { get; private set; }
48 119
49 public BSShape() 120 public BSShape()
50 { 121 {
51 referenceCount = 1; 122 referenceCount = 1;
52 lastReferenced = DateTime.Now; 123 lastReferenced = DateTime.Now;
53 physShapeInfo = new BulletShape(); 124 physShapeInfo = new BulletShape();
125 shapeInfo = new ShapeInfoInfo();
54 } 126 }
55 public BSShape(BulletShape pShape) 127 public BSShape(BulletShape pShape)
56 { 128 {
57 referenceCount = 1; 129 referenceCount = 1;
58 lastReferenced = DateTime.Now; 130 lastReferenced = DateTime.Now;
59 physShapeInfo = pShape; 131 physShapeInfo = pShape;
132 shapeInfo = new ShapeInfoInfo();
60 } 133 }
61 134
62 // Get another reference to this shape. 135 // Get another reference to this shape.
@@ -177,8 +250,7 @@ public abstract class BSShape
177 { 250 {
178 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset 251 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
179 if (prim.BaseShape.SculptEntry 252 if (prim.BaseShape.SculptEntry
180 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.FailedAssetFetch 253 && !prim.AssetFailed()
181 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.FailedMeshing
182 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting 254 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
183 && prim.BaseShape.SculptTexture != OMV.UUID.Zero 255 && prim.BaseShape.SculptTexture != OMV.UUID.Zero
184 ) 256 )
@@ -189,50 +261,46 @@ public abstract class BSShape
189 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; 261 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
190 262
191 BSPhysObject xprim = prim; 263 BSPhysObject xprim = prim;
192 Util.FireAndForget(delegate 264 RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod;
265 if (assetProvider != null)
266 {
267 BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
268 assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
193 { 269 {
194 // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID); 270 // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID);
195 RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; 271 bool assetFound = false;
196 if (assetProvider != null) 272 string mismatchIDs = String.Empty; // DEBUG DEBUG
273 if (asset != null && yprim.BaseShape.SculptEntry)
197 { 274 {
198 BSPhysObject yprim = xprim; // probably not necessary, but, just in case. 275 if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
199 assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
200 { 276 {
201 // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID); 277 yprim.BaseShape.SculptData = asset.Data;
202 bool assetFound = false; 278 // This will cause the prim to see that the filler shape is not the right
203 string mismatchIDs = String.Empty; // DEBUG DEBUG 279 // one and try again to build the object.
204 if (asset != null && yprim.BaseShape.SculptEntry) 280 // No race condition with the normal shape setting since the rebuild is at taint time.
205 { 281 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
206 if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) 282 yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
207 { 283 assetFound = true;
208 yprim.BaseShape.SculptData = asset.Data; 284 }
209 // This will cause the prim to see that the filler shape is not the right 285 else
210 // one and try again to build the object. 286 {
211 // No race condition with the normal shape setting since the rebuild is at taint time. 287 mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
212 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; 288 }
213 yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
214 assetFound = true;
215 }
216 else
217 {
218 mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
219 }
220 }
221 if (!assetFound)
222 {
223 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch;
224 }
225 physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
226 yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
227 });
228 } 289 }
229 else 290 if (!assetFound)
230 { 291 {
231 xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch; 292 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch;
232 physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
233 LogHeader, physicsScene.Name);
234 } 293 }
294 physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
295 yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
235 }); 296 });
297 }
298 else
299 {
300 xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch;
301 physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
302 LogHeader, physicsScene.Name);
303 }
236 } 304 }
237 else 305 else
238 { 306 {
@@ -288,6 +356,9 @@ public class BSShapeNull : BSShape
288} 356}
289 357
290// ============================================================================================================ 358// ============================================================================================================
359// BSShapeNative is a wrapper for a Bullet 'native' shape -- cube and sphere.
360// They are odd in that they don't allocate meshes but are computated/procedural.
361// This means allocation and freeing is different than meshes.
291public class BSShapeNative : BSShape 362public class BSShapeNative : BSShape
292{ 363{
293 private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; 364 private static string LogHeader = "[BULLETSIM SHAPE NATIVE]";
@@ -366,6 +437,7 @@ public class BSShapeNative : BSShape
366} 437}
367 438
368// ============================================================================================================ 439// ============================================================================================================
440// BSShapeMesh is a simple mesh.
369public class BSShapeMesh : BSShape 441public class BSShapeMesh : BSShape
370{ 442{
371 private static string LogHeader = "[BULLETSIM SHAPE MESH]"; 443 private static string LogHeader = "[BULLETSIM SHAPE MESH]";
@@ -395,9 +467,7 @@ public class BSShapeMesh : BSShape
395 467
396 // Check to see if mesh was created (might require an asset). 468 // Check to see if mesh was created (might require an asset).
397 newShape = VerifyMeshCreated(physicsScene, newShape, prim); 469 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
398 if (!newShape.isNativeShape 470 if (!newShape.isNativeShape || prim.AssetFailed() )
399 || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing
400 || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch)
401 { 471 {
402 // If a mesh was what was created, remember the built shape for later sharing. 472 // If a mesh was what was created, remember the built shape for later sharing.
403 // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. 473 // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh.
@@ -464,7 +534,11 @@ public class BSShapeMesh : BSShape
464 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 534 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
465 { 535 {
466 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, 536 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
467 (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); 537 (w, iC, i, vC, v) =>
538 {
539 shapeInfo.Vertices = vC;
540 return physicsScene.PE.CreateMeshShape(w, iC, i, vC, v);
541 });
468 } 542 }
469 543
470 // Code that uses the mesher to create the index/vertices info for a trimesh shape. 544 // Code that uses the mesher to create the index/vertices info for a trimesh shape.
@@ -554,11 +628,18 @@ public class BSShapeMesh : BSShape
554} 628}
555 629
556// ============================================================================================================ 630// ============================================================================================================
631// BSShapeHull is a physical shape representation htat is made up of many convex hulls.
632// The convex hulls are either supplied with the asset or are approximated by one of the
633// convex hull creation routines (in OpenSim or in Bullet).
557public class BSShapeHull : BSShape 634public class BSShapeHull : BSShape
558{ 635{
636#pragma warning disable 414
559 private static string LogHeader = "[BULLETSIM SHAPE HULL]"; 637 private static string LogHeader = "[BULLETSIM SHAPE HULL]";
638#pragma warning restore 414
639
560 public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); 640 public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>();
561 641
642
562 public BSShapeHull(BulletShape pShape) : base(pShape) 643 public BSShapeHull(BulletShape pShape) : base(pShape)
563 { 644 {
564 } 645 }
@@ -583,9 +664,7 @@ public class BSShapeHull : BSShape
583 664
584 // Check to see if hull was created (might require an asset). 665 // Check to see if hull was created (might require an asset).
585 newShape = VerifyMeshCreated(physicsScene, newShape, prim); 666 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
586 if (!newShape.isNativeShape 667 if (!newShape.isNativeShape || prim.AssetFailed())
587 || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing
588 || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch)
589 { 668 {
590 // If a mesh was what was created, remember the built shape for later sharing. 669 // If a mesh was what was created, remember the built shape for later sharing.
591 Hulls.Add(newHullKey, retHull); 670 Hulls.Add(newHullKey, retHull);
@@ -623,6 +702,7 @@ public class BSShapeHull : BSShape
623 // TODO: schedule aging and destruction of unused meshes. 702 // TODO: schedule aging and destruction of unused meshes.
624 } 703 }
625 } 704 }
705
626 List<ConvexResult> m_hulls; 706 List<ConvexResult> m_hulls;
627 private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey, 707 private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey,
628 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 708 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
@@ -655,6 +735,7 @@ public class BSShapeHull : BSShape
655 if (allHulls != null && BSParam.ShouldUseAssetHulls) 735 if (allHulls != null && BSParam.ShouldUseAssetHulls)
656 { 736 {
657 int hullCount = allHulls.Count; 737 int hullCount = allHulls.Count;
738 shapeInfo.HullCount = hullCount;
658 int totalVertices = 1; // include one for the count of the hulls 739 int totalVertices = 1; // include one for the count of the hulls
659 // Using the structure described for HACD hulls, create the memory sturcture 740 // Using the structure described for HACD hulls, create the memory sturcture
660 // to pass the hull data to the creater. 741 // to pass the hull data to the creater.
@@ -667,6 +748,7 @@ public class BSShapeHull : BSShape
667 748
668 convHulls[0] = (float)hullCount; 749 convHulls[0] = (float)hullCount;
669 int jj = 1; 750 int jj = 1;
751 int hullIndex = 0;
670 foreach (List<OMV.Vector3> hullVerts in allHulls) 752 foreach (List<OMV.Vector3> hullVerts in allHulls)
671 { 753 {
672 convHulls[jj + 0] = hullVerts.Count; 754 convHulls[jj + 0] = hullVerts.Count;
@@ -681,6 +763,8 @@ public class BSShapeHull : BSShape
681 convHulls[jj + 2] = oneVert.Z; 763 convHulls[jj + 2] = oneVert.Z;
682 jj += 3; 764 jj += 3;
683 } 765 }
766 shapeInfo.SetVerticesPerHull(hullIndex, hullVerts.Count);
767 hullIndex++;
684 } 768 }
685 769
686 // create the hull data structure in Bullet 770 // create the hull data structure in Bullet
@@ -700,7 +784,7 @@ public class BSShapeHull : BSShape
700 784
701 if (meshShape.physShapeInfo.HasPhysicalShape) 785 if (meshShape.physShapeInfo.HasPhysicalShape)
702 { 786 {
703 HACDParams parms; 787 HACDParams parms = new HACDParams();
704 parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull; 788 parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull;
705 parms.minClusters = BSParam.BHullMinClusters; 789 parms.minClusters = BSParam.BHullMinClusters;
706 parms.compacityWeight = BSParam.BHullCompacityWeight; 790 parms.compacityWeight = BSParam.BHullCompacityWeight;
@@ -710,12 +794,17 @@ public class BSShapeHull : BSShape
710 parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints); 794 parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
711 parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints); 795 parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
712 parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin); 796 parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);
797 parms.whichHACD = 0; // Use the HACD routine that comes with Bullet
713 798
714 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); 799 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
715 newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); 800 newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
716 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); 801 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape);
717 802
718 // Now done with the mesh shape. 803 // Now done with the mesh shape.
804 shapeInfo.HullCount = 1;
805 BSShapeMesh maybeMesh = meshShape as BSShapeMesh;
806 if (maybeMesh != null)
807 shapeInfo.SetVerticesPerHull(0, maybeMesh.shapeInfo.Vertices);
719 meshShape.Dereference(physicsScene); 808 meshShape.Dereference(physicsScene);
720 } 809 }
721 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 810 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
@@ -865,6 +954,8 @@ public class BSShapeHull : BSShape
865} 954}
866 955
867// ============================================================================================================ 956// ============================================================================================================
957// BSShapeCompound is a wrapper for the Bullet compound shape which is built from multiple, separate
958// meshes. Used by BulletSim for complex shapes like linksets.
868public class BSShapeCompound : BSShape 959public class BSShapeCompound : BSShape
869{ 960{
870 private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; 961 private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
@@ -993,6 +1084,11 @@ public class BSShapeCompound : BSShape
993 BSShapeNative nativeShape = new BSShapeNative(pShape); 1084 BSShapeNative nativeShape = new BSShapeNative(pShape);
994 nativeShape.Dereference(physicsScene); 1085 nativeShape.Dereference(physicsScene);
995 } 1086 }
1087 else
1088 {
1089 physicsScene.Logger.WarnFormat("{0} DereferenceAnonCollisionShape. Did not find shape. {1}",
1090 LogHeader, pShape);
1091 }
996 } 1092 }
997 } 1093 }
998 } 1094 }
@@ -1002,9 +1098,15 @@ public class BSShapeCompound : BSShape
1002} 1098}
1003 1099
1004// ============================================================================================================ 1100// ============================================================================================================
1101// BSShapeConvexHull is a wrapper for a Bullet single convex hull. A BSShapeHull contains multiple convex
1102// hull shapes. This is used for simple prims that are convex and thus can be made into a simple
1103// collision shape (a single hull). More complex physical shapes will be BSShapeHull's.
1005public class BSShapeConvexHull : BSShape 1104public class BSShapeConvexHull : BSShape
1006{ 1105{
1106#pragma warning disable 414
1007 private static string LogHeader = "[BULLETSIM SHAPE CONVEX HULL]"; 1107 private static string LogHeader = "[BULLETSIM SHAPE CONVEX HULL]";
1108#pragma warning restore 414
1109
1008 public static Dictionary<System.UInt64, BSShapeConvexHull> ConvexHulls = new Dictionary<System.UInt64, BSShapeConvexHull>(); 1110 public static Dictionary<System.UInt64, BSShapeConvexHull> ConvexHulls = new Dictionary<System.UInt64, BSShapeConvexHull>();
1009 1111
1010 public BSShapeConvexHull(BulletShape pShape) : base(pShape) 1112 public BSShapeConvexHull(BulletShape pShape) : base(pShape)
@@ -1098,9 +1200,15 @@ public class BSShapeConvexHull : BSShape
1098 } 1200 }
1099} 1201}
1100// ============================================================================================================ 1202// ============================================================================================================
1203// BSShapeGImpact is a wrapper for the Bullet GImpact shape which is a collision mesh shape that
1204// can handle concave as well as convex shapes. Much slower computationally but creates smoother
1205// shapes than multiple convex hull approximations.
1101public class BSShapeGImpact : BSShape 1206public class BSShapeGImpact : BSShape
1102{ 1207{
1208#pragma warning disable 414
1103 private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; 1209 private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]";
1210#pragma warning restore 414
1211
1104 public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>(); 1212 public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>();
1105 1213
1106 public BSShapeGImpact(BulletShape pShape) : base(pShape) 1214 public BSShapeGImpact(BulletShape pShape) : base(pShape)
@@ -1130,9 +1238,7 @@ public class BSShapeGImpact : BSShape
1130 // Check to see if mesh was created (might require an asset). 1238 // Check to see if mesh was created (might require an asset).
1131 newShape = VerifyMeshCreated(physicsScene, newShape, prim); 1239 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
1132 newShape.shapeKey = newMeshKey; 1240 newShape.shapeKey = newMeshKey;
1133 if (!newShape.isNativeShape 1241 if (!newShape.isNativeShape || prim.AssetFailed())
1134 || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing
1135 || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch)
1136 { 1242 {
1137 // If a mesh was what was created, remember the built shape for later sharing. 1243 // If a mesh was what was created, remember the built shape for later sharing.
1138 // Also note that if meshing failed we put it in the mesh list as there is nothing 1244 // Also note that if meshing failed we put it in the mesh list as there is nothing
@@ -1150,7 +1256,11 @@ public class BSShapeGImpact : BSShape
1150 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 1256 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
1151 { 1257 {
1152 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, 1258 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
1153 (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); 1259 (w, iC, i, vC, v) =>
1260 {
1261 shapeInfo.Vertices = vC;
1262 return physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v);
1263 });
1154 } 1264 }
1155 1265
1156 public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) 1266 public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
@@ -1205,10 +1315,15 @@ public class BSShapeGImpact : BSShape
1205} 1315}
1206 1316
1207// ============================================================================================================ 1317// ============================================================================================================
1318// BSShapeAvatar is a specialized mesh shape for avatars.
1208public class BSShapeAvatar : BSShape 1319public class BSShapeAvatar : BSShape
1209{ 1320{
1321#pragma warning disable 414
1210 private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; 1322 private static string LogHeader = "[BULLETSIM SHAPE AVATAR]";
1211 public BSShapeAvatar() : base() 1323#pragma warning restore 414
1324
1325 public BSShapeAvatar()
1326 : base()
1212 { 1327 {
1213 } 1328 }
1214 public static BSShape GetReference(BSPhysObject prim) 1329 public static BSShape GetReference(BSPhysObject prim)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
index 8888d6d..d70b2fb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
@@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
58 { 58 {
59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; 59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
60 } 60 }
61 m_mapInfo = new BulletHMapInfo(id, initialMap); 61 m_mapInfo = new BulletHMapInfo(id, initialMap, regionSize.X, regionSize.Y);
62 m_mapInfo.minCoords = minTerrainCoords; 62 m_mapInfo.minCoords = minTerrainCoords;
63 m_mapInfo.maxCoords = maxTerrainCoords; 63 m_mapInfo.maxCoords = maxTerrainCoords;
64 m_mapInfo.terrainRegionBase = TerrainBase; 64 m_mapInfo.terrainRegionBase = TerrainBase;
@@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
72 Vector3 minCoords, Vector3 maxCoords) 72 Vector3 minCoords, Vector3 maxCoords)
73 : base(physicsScene, regionBase, id) 73 : base(physicsScene, regionBase, id)
74 { 74 {
75 m_mapInfo = new BulletHMapInfo(id, initialMap); 75 m_mapInfo = new BulletHMapInfo(id, initialMap, maxCoords.X - minCoords.X, maxCoords.Y - minCoords.Y);
76 m_mapInfo.minCoords = minCoords; 76 m_mapInfo.minCoords = minCoords;
77 m_mapInfo.maxCoords = maxCoords; 77 m_mapInfo.maxCoords = maxCoords;
78 m_mapInfo.minZ = minCoords.Z; 78 m_mapInfo.minZ = minCoords.Z;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 441d2d3..50f917a 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -111,9 +111,11 @@ public sealed class BSTerrainManager : IDisposable
111 private Vector3 m_worldMax; 111 private Vector3 m_worldMax;
112 private PhysicsScene MegaRegionParentPhysicsScene { get; set; } 112 private PhysicsScene MegaRegionParentPhysicsScene { get; set; }
113 113
114 public BSTerrainManager(BSScene physicsScene) 114 public BSTerrainManager(BSScene physicsScene, Vector3 regionSize)
115 { 115 {
116 m_physicsScene = physicsScene; 116 m_physicsScene = physicsScene;
117 DefaultRegionSize = regionSize;
118
117 m_terrains = new Dictionary<Vector3,BSTerrainPhys>(); 119 m_terrains = new Dictionary<Vector3,BSTerrainPhys>();
118 120
119 // Assume one region of default size 121 // Assume one region of default size
@@ -135,8 +137,9 @@ public sealed class BSTerrainManager : IDisposable
135 DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, m_physicsScene.RegionName); 137 DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, m_physicsScene.RegionName);
136 // The ground plane is here to catch things that are trying to drop to negative infinity 138 // The ground plane is here to catch things that are trying to drop to negative infinity
137 BulletShape groundPlaneShape = m_physicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); 139 BulletShape groundPlaneShape = m_physicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin);
140 Vector3 groundPlaneAltitude = new Vector3(0f, 0f, BSParam.TerrainGroundPlane);
138 m_groundPlane = m_physicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, 141 m_groundPlane = m_physicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
139 BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity); 142 BSScene.GROUNDPLANE_ID, groundPlaneAltitude, Quaternion.Identity);
140 143
141 // Everything collides with the ground plane. 144 // Everything collides with the ground plane.
142 m_groundPlane.collisionType = CollisionType.Groundplane; 145 m_groundPlane.collisionType = CollisionType.Groundplane;
@@ -237,9 +240,6 @@ public sealed class BSTerrainManager : IDisposable
237 // Called during taint-time. 240 // Called during taint-time.
238 private void UpdateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords) 241 private void UpdateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
239 { 242 {
240 DetailLog("{0},BSTerrainManager.UpdateTerrain,call,id={1},minC={2},maxC={3}",
241 BSScene.DetailLogZero, id, minCoords, maxCoords);
242
243 // Find high and low points of passed heightmap. 243 // Find high and low points of passed heightmap.
244 // The min and max passed in is usually the area objects can be in (maximum 244 // The min and max passed in is usually the area objects can be in (maximum
245 // object height, for instance). The terrain wants the bounding box for the 245 // object height, for instance). The terrain wants the bounding box for the
@@ -259,6 +259,9 @@ public sealed class BSTerrainManager : IDisposable
259 minCoords.Z = minZ; 259 minCoords.Z = minZ;
260 maxCoords.Z = maxZ; 260 maxCoords.Z = maxZ;
261 261
262 DetailLog("{0},BSTerrainManager.UpdateTerrain,call,id={1},minC={2},maxC={3}",
263 BSScene.DetailLogZero, id, minCoords, maxCoords);
264
262 Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); 265 Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
263 266
264 lock (m_terrains) 267 lock (m_terrains)
@@ -267,8 +270,8 @@ public sealed class BSTerrainManager : IDisposable
267 if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) 270 if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
268 { 271 {
269 // There is already a terrain in this spot. Free the old and build the new. 272 // There is already a terrain in this spot. Free the old and build the new.
270 DetailLog("{0},BSTErrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", 273 DetailLog("{0},BSTerrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
271 BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); 274 BSScene.DetailLogZero, id, terrainRegionBase, minCoords, maxCoords);
272 275
273 // Remove old terrain from the collection 276 // Remove old terrain from the collection
274 m_terrains.Remove(terrainRegionBase); 277 m_terrains.Remove(terrainRegionBase);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
index 971ff9f..5932461 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
@@ -165,14 +165,15 @@ public class BulletConstraint
165// than making copies. 165// than making copies.
166public class BulletHMapInfo 166public class BulletHMapInfo
167{ 167{
168 public BulletHMapInfo(uint id, float[] hm) { 168 public BulletHMapInfo(uint id, float[] hm, float pSizeX, float pSizeY) {
169 ID = id; 169 ID = id;
170 heightMap = hm; 170 heightMap = hm;
171 terrainRegionBase = OMV.Vector3.Zero; 171 terrainRegionBase = OMV.Vector3.Zero;
172 minCoords = new OMV.Vector3(100f, 100f, 25f); 172 minCoords = new OMV.Vector3(100f, 100f, 25f);
173 maxCoords = new OMV.Vector3(101f, 101f, 26f); 173 maxCoords = new OMV.Vector3(101f, 101f, 26f);
174 minZ = maxZ = 0f; 174 minZ = maxZ = 0f;
175 sizeX = sizeY = 256f; 175 sizeX = pSizeX;
176 sizeY = pSizeY;
176 } 177 }
177 public uint ID; 178 public uint ID;
178 public float[] heightMap; 179 public float[] heightMap;
@@ -189,6 +190,7 @@ public class BulletHMapInfo
189public enum CollisionType 190public enum CollisionType
190{ 191{
191 Avatar, 192 Avatar,
193 PhantomToOthersAvatar, // An avatar that it phantom to other avatars but not to anything else
192 Groundplane, 194 Groundplane,
193 Terrain, 195 Terrain,
194 Static, 196 Static,
@@ -230,7 +232,12 @@ public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeM
230 { CollisionType.Avatar, 232 { CollisionType.Avatar,
231 new CollisionTypeFilterGroup(CollisionType.Avatar, 233 new CollisionTypeFilterGroup(CollisionType.Avatar,
232 (uint)CollisionFilterGroups.BCharacterGroup, 234 (uint)CollisionFilterGroups.BCharacterGroup,
233 (uint)CollisionFilterGroups.BAllGroup) 235 (uint)(CollisionFilterGroups.BAllGroup))
236 },
237 { CollisionType.PhantomToOthersAvatar,
238 new CollisionTypeFilterGroup(CollisionType.PhantomToOthersAvatar,
239 (uint)CollisionFilterGroups.BCharacterGroup,
240 (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BCharacterGroup))
234 }, 241 },
235 { CollisionType.Groundplane, 242 { CollisionType.Groundplane,
236 new CollisionTypeFilterGroup(CollisionType.Groundplane, 243 new CollisionTypeFilterGroup(CollisionType.Groundplane,
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs
index d069178..4f90eee 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.8.0.*")] 32[assembly: AssemblyVersion("0.8.2.*")]
33 33
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
index 28207a4..775bca2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
@@ -28,15 +28,16 @@
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq;
32using System.Text; 31using System.Text;
33 32
34using Nini.Config; 33using Nini.Config;
35 34
36using OpenSim.Framework; 35using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin; 36using OpenSim.Region.Physics.Manager;
38using OpenSim.Region.Physics.Meshing; 37using OpenSim.Region.Physics.Meshing;
39 38
39using OpenMetaverse;
40
40namespace OpenSim.Region.Physics.BulletSPlugin.Tests 41namespace OpenSim.Region.Physics.BulletSPlugin.Tests
41{ 42{
42// Utility functions for building up and tearing down the sample physics environments 43// Utility functions for building up and tearing down the sample physics environments
@@ -77,17 +78,21 @@ public static class BulletSimTestsUtil
77 bulletSimConfig.Set("VehicleLoggingEnabled","True"); 78 bulletSimConfig.Set("VehicleLoggingEnabled","True");
78 } 79 }
79 80
80 BSPlugin bsPlugin = new BSPlugin(); 81 PhysicsPluginManager physicsPluginManager;
82 physicsPluginManager = new PhysicsPluginManager();
83 physicsPluginManager.LoadPluginsFromAssemblies("Physics");
84
85 Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
86
87 PhysicsScene pScene = physicsPluginManager.GetPhysicsScene(
88 "BulletSim", "Meshmerizer", openSimINI, "BSTestRegion", regionExtent);
81 89
82 BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); 90 BSScene bsScene = pScene as BSScene;
83 91
84 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube. 92 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube.
85 // In the future, add a fake asset fetcher to get meshes and sculpts. 93 // In the future, add a fake asset fetcher to get meshes and sculpts.
86 // bsScene.RequestAssetMethod = ???; 94 // bsScene.RequestAssetMethod = ???;
87 95
88 Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI);
89 bsScene.Initialise(mesher, openSimINI);
90
91 return bsScene; 96 return bsScene;
92 } 97 }
93 98
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs
new file mode 100644
index 0000000..5a5de11
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs
@@ -0,0 +1,205 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using NUnit.Framework;
34using log4net;
35
36using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin;
38using OpenSim.Region.Physics.Manager;
39using OpenSim.Tests.Common;
40
41using OpenMetaverse;
42
43namespace OpenSim.Region.Physics.BulletSPlugin.Tests
44{
45[TestFixture]
46public class HullCreation : OpenSimTestCase
47{
48 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
49 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
50
51 BSScene PhysicsScene { get; set; }
52 Vector3 ObjectInitPosition;
53
54 [TestFixtureSetUp]
55 public void Init()
56 {
57
58 }
59
60 [TestFixtureTearDown]
61 public void TearDown()
62 {
63 if (PhysicsScene != null)
64 {
65 // The Dispose() will also free any physical objects in the scene
66 PhysicsScene.Dispose();
67 PhysicsScene = null;
68 }
69 }
70
71 [TestCase(7, 2, 5f, 5f, 32, 0f)] /* default hull parameters */
72 public void GeomHullConvexDecomp( int maxDepthSplit,
73 int maxDepthSplitForSimpleShapes,
74 float concavityThresholdPercent,
75 float volumeConservationThresholdPercent,
76 int maxVertices,
77 float maxSkinWidth)
78 {
79 // Setup the physics engine to use the C# version of convex decomp
80 Dictionary<string, string> engineParams = new Dictionary<string, string>();
81 engineParams.Add("MeshSculptedPrim", "true"); // ShouldMeshSculptedPrim
82 engineParams.Add("ForceSimplePrimMeshing", "false"); // ShouldForceSimplePrimMeshing
83 engineParams.Add("UseHullsForPhysicalObjects", "true"); // ShouldUseHullsForPhysicalObjects
84 engineParams.Add("ShouldRemoveZeroWidthTriangles", "true");
85 engineParams.Add("ShouldUseBulletHACD", "false");
86 engineParams.Add("ShouldUseSingleConvexHullForPrims", "true");
87 engineParams.Add("ShouldUseGImpactShapeForPrims", "false");
88 engineParams.Add("ShouldUseAssetHulls", "true");
89
90 engineParams.Add("CSHullMaxDepthSplit", maxDepthSplit.ToString());
91 engineParams.Add("CSHullMaxDepthSplitForSimpleShapes", maxDepthSplitForSimpleShapes.ToString());
92 engineParams.Add("CSHullConcavityThresholdPercent", concavityThresholdPercent.ToString());
93 engineParams.Add("CSHullVolumeConservationThresholdPercent", volumeConservationThresholdPercent.ToString());
94 engineParams.Add("CSHullMaxVertices", maxVertices.ToString());
95 engineParams.Add("CSHullMaxSkinWidth", maxSkinWidth.ToString());
96
97 PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
98
99 PrimitiveBaseShape pbs;
100 Vector3 pos;
101 Vector3 size;
102 Quaternion rot;
103 bool isPhys;
104
105 // Cylinder
106 pbs = PrimitiveBaseShape.CreateCylinder();
107 pos = new Vector3(100.0f, 100.0f, 0f);
108 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f;
109 ObjectInitPosition = pos;
110 size = new Vector3(2f, 2f, 2f);
111 pbs.Scale = size;
112 rot = Quaternion.Identity;
113 isPhys = true;
114 uint cylinderLocalID = 123;
115 PhysicsScene.AddPrimShape("testCylinder", pbs, pos, size, rot, isPhys, cylinderLocalID);
116 BSPrim primTypeCylinder = (BSPrim)PhysicsScene.PhysObjects[cylinderLocalID];
117
118 // Hollow Cylinder
119 pbs = PrimitiveBaseShape.CreateCylinder();
120 pbs.ProfileHollow = (ushort)(0.70f * 50000);
121 pos = new Vector3(110.0f, 110.0f, 0f);
122 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f;
123 ObjectInitPosition = pos;
124 size = new Vector3(2f, 2f, 2f);
125 pbs.Scale = size;
126 rot = Quaternion.Identity;
127 isPhys = true;
128 uint hollowCylinderLocalID = 124;
129 PhysicsScene.AddPrimShape("testHollowCylinder", pbs, pos, size, rot, isPhys, hollowCylinderLocalID);
130 BSPrim primTypeHollowCylinder = (BSPrim)PhysicsScene.PhysObjects[hollowCylinderLocalID];
131
132 // Torus
133 // ProfileCurve = Circle, PathCurve = Curve1
134 pbs = PrimitiveBaseShape.CreateSphere();
135 pbs.ProfileShape = (byte)ProfileShape.Circle;
136 pbs.PathCurve = (byte)Extrusion.Curve1;
137 pbs.PathScaleX = 100; // default hollow info as set in the viewer
138 pbs.PathScaleY = (int)(.25f / 0.01f) + 200;
139 pos = new Vector3(120.0f, 120.0f, 0f);
140 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f;
141 ObjectInitPosition = pos;
142 size = new Vector3(2f, 4f, 4f);
143 pbs.Scale = size;
144 rot = Quaternion.Identity;
145 isPhys = true;
146 uint torusLocalID = 125;
147 PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID);
148 BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID];
149
150 // The actual prim shape creation happens at taint time
151 PhysicsScene.ProcessTaints();
152
153 // Check out the created hull shapes and report their characteristics
154 ReportShapeGeom(primTypeCylinder);
155 ReportShapeGeom(primTypeHollowCylinder);
156 ReportShapeGeom(primTypeTorus);
157 }
158
159 [TestCase]
160 public void GeomHullBulletHACD()
161 {
162 // Cylinder
163 // Hollow Cylinder
164 // Torus
165 }
166
167 private void ReportShapeGeom(BSPrim prim)
168 {
169 if (prim != null)
170 {
171 if (prim.PhysShape.HasPhysicalShape)
172 {
173 BSShape physShape = prim.PhysShape;
174 string shapeType = physShape.GetType().ToString();
175 switch (shapeType)
176 {
177 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeNative":
178 BSShapeNative nShape = physShape as BSShapeNative;
179 prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType);
180 break;
181 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeMesh":
182 BSShapeMesh mShape = physShape as BSShapeMesh;
183 prim.PhysScene.DetailLog("{0}, mesh, shapeInfo={1}", prim.Name, mShape.shapeInfo);
184 break;
185 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeHull":
186 // BSShapeHull hShape = physShape as BSShapeHull;
187 // prim.PhysScene.DetailLog("{0}, hull, shapeInfo={1}", prim.Name, hShape.shapeInfo);
188 break;
189 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeConvexHull":
190 BSShapeConvexHull chShape = physShape as BSShapeConvexHull;
191 prim.PhysScene.DetailLog("{0}, convexHull, shapeInfo={1}", prim.Name, chShape.shapeInfo);
192 break;
193 case "OpenSim.Region.Physics.BulletSPlugin.BSShapeCompound":
194 BSShapeCompound cShape = physShape as BSShapeCompound;
195 prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType);
196 break;
197 default:
198 prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType);
199 break;
200 }
201 }
202 }
203 }
204}
205} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
index b8cf624..c5867b2 100644
--- a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
32// You can specify all the values or you can default the Build and Revision Numbers 32// You can specify all the values or you can default the Build and Revision Numbers
33// by using the '*' as shown below: 33// by using the '*' as shown below:
34// [assembly: AssemblyVersion("1.0.*")] 34// [assembly: AssemblyVersion("1.0.*")]
35[assembly: AssemblyVersion("0.8.0.*")] 35[assembly: AssemblyVersion("0.8.2.*")]
36 36
diff --git a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs
index 10e850e..33f60e4 100644
--- a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
55// You can specify all values by your own or you can build default build and revision 55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default): 56// numbers with the '*' character (the default):
57 57
58[assembly : AssemblyVersion("0.8.0.*")] 58[assembly : AssemblyVersion("0.8.2.*")]
diff --git a/OpenSim/Region/Physics/Manager/NullPhysicsScene.cs b/OpenSim/Region/Physics/Manager/NullPhysicsScene.cs
index 1ccf46d..b52f1f6 100644
--- a/OpenSim/Region/Physics/Manager/NullPhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/NullPhysicsScene.cs
@@ -45,7 +45,8 @@ namespace OpenSim.Region.Physics.Manager
45 // Does nothing right now 45 // Does nothing right now
46 } 46 }
47 47
48 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 48 public override PhysicsActor AddAvatar(
49 string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
49 { 50 {
50 m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddAvatar({0})", position); 51 m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddAvatar({0})", position);
51 return PhysicsActor.Null; 52 return PhysicsActor.Null;
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 44bfd42..60f6480 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -386,7 +386,7 @@ namespace OpenSim.Region.Physics.Manager
386 386
387 // Used for MoveTo 387 // Used for MoveTo
388 public abstract Vector3 PIDTarget { set; } 388 public abstract Vector3 PIDTarget { set; }
389 public abstract bool PIDActive { set;} 389 public abstract bool PIDActive { get; set; }
390 public abstract float PIDTau { set; } 390 public abstract float PIDTau { set; }
391 391
392 // Used for llSetHoverHeight and maybe vehicle height 392 // Used for llSetHoverHeight and maybe vehicle height
@@ -611,7 +611,13 @@ namespace OpenSim.Region.Physics.Manager
611 } 611 }
612 612
613 public override Vector3 PIDTarget { set { return; } } 613 public override Vector3 PIDTarget { set { return; } }
614 public override bool PIDActive { set { return; } } 614
615 public override bool PIDActive
616 {
617 get { return false; }
618 set { return; }
619 }
620
615 public override float PIDTau { set { return; } } 621 public override float PIDTau { set { return; } }
616 622
617 public override float PIDHoverHeight { set { return; } } 623 public override float PIDHoverHeight { set { return; } }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index d14edfd..ddbe80b 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -180,7 +180,7 @@ namespace OpenSim.Region.Physics.Manager
180 { 180 {
181 if (!pluginType.IsAbstract) 181 if (!pluginType.IsAbstract)
182 { 182 {
183 Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true); 183 Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin");
184 184
185 if (physTypeInterface != null) 185 if (physTypeInterface != null)
186 { 186 {
@@ -194,7 +194,7 @@ namespace OpenSim.Region.Physics.Manager
194 } 194 }
195 } 195 }
196 196
197 Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true); 197 Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin");
198 198
199 if (meshTypeInterface != null) 199 if (meshTypeInterface != null)
200 { 200 {
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 4f4ff07..96ef0a6 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -148,26 +148,38 @@ namespace OpenSim.Region.Physics.Manager
148 /// </summary> 148 /// </summary>
149 /// <param name="avName"></param> 149 /// <param name="avName"></param>
150 /// <param name="position"></param> 150 /// <param name="position"></param>
151 /// <param name="velocity"></param>
151 /// <param name="size"></param> 152 /// <param name="size"></param>
152 /// <param name="isFlying"></param> 153 /// <param name="isFlying"></param>
153 /// <returns></returns> 154 /// <returns></returns>
155<<<<<<< HEAD
156 public abstract PhysicsActor AddAvatar(
157 string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying);
158
159=======
154 public virtual PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 160 public virtual PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
155 { 161 {
156 return null; 162 return null;
157 } 163 }
164>>>>>>> avn/ubitvar
158 /// <summary> 165 /// <summary>
159 /// Add an avatar 166 /// Add an avatar
160 /// </summary> 167 /// </summary>
161 /// <param name="localID"></param> 168 /// <param name="localID"></param>
162 /// <param name="avName"></param> 169 /// <param name="avName"></param>
163 /// <param name="position"></param> 170 /// <param name="position"></param>
171 /// <param name="velocity"></param>
164 /// <param name="size"></param> 172 /// <param name="size"></param>
165 /// <param name="isFlying"></param> 173 /// <param name="isFlying"></param>
166 /// <returns></returns> 174 /// <returns></returns>
167 public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) 175 public virtual PhysicsActor AddAvatar(
176 uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
168 { 177 {
169 PhysicsActor ret = AddAvatar(avName, position, size, isFlying); 178 PhysicsActor ret = AddAvatar(avName, position, velocity, size, isFlying);
170 if (ret != null) ret.LocalID = localID; 179
180 if (ret != null)
181 ret.LocalID = localID;
182
171 return ret; 183 return ret;
172 } 184 }
173 185
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index d67d4d2..ef6482a 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -84,7 +84,8 @@ namespace OpenSim.Region.Physics.Meshing
84 private List<List<Vector3>> mConvexHulls = null; 84 private List<List<Vector3>> mConvexHulls = null;
85 private List<Vector3> mBoundingHull = null; 85 private List<Vector3> mBoundingHull = null;
86 86
87 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 87 // Mesh cache. Static so it can be shared across instances of this class
88 private static Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
88 89
89 public Meshmerizer(IConfigSource config) 90 public Meshmerizer(IConfigSource config)
90 { 91 {
@@ -937,8 +938,11 @@ namespace OpenSim.Region.Physics.Meshing
937 if (shouldCache) 938 if (shouldCache)
938 { 939 {
939 key = primShape.GetMeshKey(size, lod); 940 key = primShape.GetMeshKey(size, lod);
940 if (m_uniqueMeshes.TryGetValue(key, out mesh)) 941 lock (m_uniqueMeshes)
941 return mesh; 942 {
943 if (m_uniqueMeshes.TryGetValue(key, out mesh))
944 return mesh;
945 }
942 } 946 }
943 947
944 if (size.X < 0.01f) size.X = 0.01f; 948 if (size.X < 0.01f) size.X = 0.01f;
@@ -964,7 +968,10 @@ namespace OpenSim.Region.Physics.Meshing
964 968
965 if (shouldCache) 969 if (shouldCache)
966 { 970 {
967 m_uniqueMeshes.Add(key, mesh); 971 lock (m_uniqueMeshes)
972 {
973 m_uniqueMeshes.Add(key, mesh);
974 }
968 } 975 }
969 } 976 }
970 977
diff --git a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs
index 8542753..ec968c0 100644
--- a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.8.0.*")] 32[assembly: AssemblyVersion("0.8.2.*")]
33 33
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 43bef3c..9203169 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1251,8 +1251,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1251 public override Vector3 PIDTarget { set { return; } } 1251 public override Vector3 PIDTarget { set { return; } }
1252 public override bool PIDActive 1252 public override bool PIDActive
1253 { 1253 {
1254<<<<<<< HEAD
1255 get { return false; }
1256=======
1254 // os version 1257 // os version
1255 // get { return false; } 1258 // get { return false; }
1259>>>>>>> avn/ubitvar
1256 set { return; } 1260 set { return; }
1257 } 1261 }
1258 public override float PIDTau { set { return; } } 1262 public override float PIDTau { set { return; } }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 218ccda..6363422 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -114,7 +114,6 @@ namespace OpenSim.Region.Physics.OdePlugin
114 private float m_PIDTau; 114 private float m_PIDTau;
115 private float PID_D = 35f; 115 private float PID_D = 35f;
116 private float PID_G = 25f; 116 private float PID_G = 25f;
117 private bool m_usePID;
118 117
119 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), 118 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
120 // and are for non-VEHICLES only. 119 // and are for non-VEHICLES only.
@@ -1731,7 +1730,7 @@ Console.WriteLine(" JointCreateFixed");
1731 // gravityz multiplier = 1 - m_buoyancy 1730 // gravityz multiplier = 1 - m_buoyancy
1732 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; 1731 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass;
1733 1732
1734 if (m_usePID) 1733 if (PIDActive)
1735 { 1734 {
1736//Console.WriteLine("PID " + Name); 1735//Console.WriteLine("PID " + Name);
1737 // KF - this is for object move? eg. llSetPos() ? 1736 // KF - this is for object move? eg. llSetPos() ?
@@ -1803,7 +1802,7 @@ Console.WriteLine(" JointCreateFixed");
1803 } // end if (PIDActive) 1802 } // end if (PIDActive)
1804 1803
1805 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller 1804 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller
1806 if (m_useHoverPID && !m_usePID) 1805 if (m_useHoverPID && !PIDActive)
1807 { 1806 {
1808//Console.WriteLine("Hover " + Name); 1807//Console.WriteLine("Hover " + Name);
1809 1808
@@ -2875,7 +2874,7 @@ Console.WriteLine(" JointCreateFixed");
2875 // it does make sense to do this for tiny little instabilities with physical prim, however 0.5m/frame is fairly large. 2874 // it does make sense to do this for tiny little instabilities with physical prim, however 0.5m/frame is fairly large.
2876 // reducing this to 0.02m/frame seems to help the angular rubberbanding quite a bit, however, to make sure it doesn't affect elevators and vehicles 2875 // reducing this to 0.02m/frame seems to help the angular rubberbanding quite a bit, however, to make sure it doesn't affect elevators and vehicles
2877 // adding these logical exclusion situations to maintain this where I think it was intended to be. 2876 // adding these logical exclusion situations to maintain this where I think it was intended to be.
2878 if (m_throttleUpdates || m_usePID || (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero)) 2877 if (m_throttleUpdates || PIDActive || (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero))
2879 { 2878 {
2880 m_minvelocity = 0.5f; 2879 m_minvelocity = 0.5f;
2881 } 2880 }
@@ -2956,10 +2955,14 @@ Console.WriteLine(" JointCreateFixed");
2956 m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name); 2955 m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name);
2957 } 2956 }
2958 } 2957 }
2958<<<<<<< HEAD
2959 public override bool PIDActive { get; set; }
2960=======
2959 // os version 2961 // os version
2960 //public override bool PIDActive {get { return m_usePID; } set { m_usePID = value; } } 2962 //public override bool PIDActive {get { return m_usePID; } set { m_usePID = value; } }
2961 public override bool PIDActive { set { m_usePID = value; } } 2963 public override bool PIDActive { set { m_usePID = value; } }
2962 2964
2965>>>>>>> avn/ubitvar
2963 public override float PIDTau { set { m_PIDTau = value; } } 2966 public override float PIDTau { set { m_PIDTau = value; } }
2964 2967
2965 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2968 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
@@ -3356,10 +3359,14 @@ Console.WriteLine(" JointCreateFixed");
3356 RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod; 3359 RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod;
3357 if (assetProvider != null) 3360 if (assetProvider != null)
3358 assetProvider(_pbs.SculptTexture, MeshAssetReceived); 3361 assetProvider(_pbs.SculptTexture, MeshAssetReceived);
3362<<<<<<< HEAD
3363 }, null, "ODEPrim.CheckMeshAsset");
3364=======
3359 // os version 3365 // os version
3360 //}, null, "ODEPrim.CheckMeshAsset"); 3366 //}, null, "ODEPrim.CheckMeshAsset");
3361 // avn 3367 // avn
3362 }); 3368 });
3369>>>>>>> avn/ubitvar
3363 } 3370 }
3364 } 3371 }
3365 3372
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 820e649..7f4a809 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -2020,6 +2020,13 @@ namespace OpenSim.Region.Physics.OdePlugin
2020 2020
2021 #region Add/Remove Entities 2021 #region Add/Remove Entities
2022 2022
2023<<<<<<< HEAD
2024 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
2025 {
2026 OdeCharacter newAv
2027 = new OdeCharacter(
2028 avName, this, position, velocity, size, avPIDD, avPIDP,
2029=======
2023/* core version 2030/* core version
2024 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) 2031 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
2025 { 2032 {
@@ -2041,6 +2048,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2041 OdeCharacter newAv 2048 OdeCharacter newAv
2042 = new OdeCharacter( 2049 = new OdeCharacter(
2043 avName, this, position, Vector3.Zero, size, avPIDD, avPIDP, 2050 avName, this, position, Vector3.Zero, size, avPIDD, avPIDP,
2051>>>>>>> avn/ubitvar
2044 avCapRadius, avStandupTensor, avDensity, 2052 avCapRadius, avStandupTensor, avDensity,
2045 avMovementDivisorWalk, avMovementDivisorRun); 2053 avMovementDivisorWalk, avMovementDivisorRun);
2046 2054
diff --git a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs
index 83be103..fc1ffba 100644
--- a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
55// You can specify all values by your own or you can build default build and revision 55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default): 56// numbers with the '*' character (the default):
57 57
58[assembly : AssemblyVersion("0.8.0.*")] 58[assembly : AssemblyVersion("0.8.2.*")]
diff --git a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
index ae534ea..40ab984 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
@@ -273,9 +273,10 @@ namespace OpenSim.Region.Physics.POSPlugin
273 set { return; } 273 set { return; }
274 } 274 }
275 275
276 public override bool PIDActive 276 public override bool PIDActive
277 { 277 {
278 set { return; } 278 get { return false; }
279 set { return; }
279 } 280 }
280 281
281 public override float PIDTau 282 public override float PIDTau
diff --git a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
index 2ea8bfc..782ba82 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
@@ -270,6 +270,7 @@ namespace OpenSim.Region.Physics.POSPlugin
270 270
271 public override bool PIDActive 271 public override bool PIDActive
272 { 272 {
273 get { return false; }
273 set { return; } 274 set { return; }
274 } 275 }
275 276
diff --git a/OpenSim/Region/Physics/POSPlugin/POSScene.cs b/OpenSim/Region/Physics/POSPlugin/POSScene.cs
index d30d482..080c6ab 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSScene.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSScene.cs
@@ -58,7 +58,8 @@ namespace OpenSim.Region.Physics.POSPlugin
58 { 58 {
59 } 59 }
60 60
61 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 61 public override PhysicsActor AddAvatar(
62 string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
62 { 63 {
63 POSCharacter act = new POSCharacter(); 64 POSCharacter act = new POSCharacter();
64 act.Position = position; 65 act.Position = position;