diff options
Diffstat (limited to 'OpenSim/Region/Physics')
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; | |||
30 | using System.Linq; | 30 | using System.Linq; |
31 | using System.Text; | 31 | using System.Text; |
32 | 32 | ||
33 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Physics.Manager; | 34 | using OpenSim.Region.Physics.Manager; |
34 | 35 | ||
35 | using OMV = OpenMetaverse; | 36 | using 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 | { |
37 | public class BSActorLockAxis : BSActor | 37 | public 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 | { |
33 | public class BSActorCollection | 33 | public 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 | ||
38 | public sealed class BSLinksetCompound : BSLinkset | 38 | public 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; | |||
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Physics.Manager; | 35 | using OpenSim.Region.Physics.Manager; |
36 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 36 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
37 | using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics | ||
37 | 38 | ||
38 | namespace OpenSim.Region.Physics.BulletSPlugin | 39 | namespace 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; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Threading; | 33 | using System.Threading; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Monitoring; | ||
35 | using OpenSim.Region.Framework; | 36 | using OpenSim.Region.Framework; |
36 | using OpenSim.Region.CoreModules; | 37 | using OpenSim.Region.CoreModules; |
37 | using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging; | 38 | using 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 | { |
37 | public sealed class BSShapeCollection : IDisposable | 37 | public 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 | ||
39 | namespace OpenSim.Region.Physics.BulletSPlugin | 39 | namespace 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. | ||
45 | public 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 | |||
41 | public abstract class BSShape | 111 | public 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. | ||
291 | public class BSShapeNative : BSShape | 362 | public 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. | ||
369 | public class BSShapeMesh : BSShape | 441 | public 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). | ||
557 | public class BSShapeHull : BSShape | 634 | public 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. | ||
868 | public class BSShapeCompound : BSShape | 959 | public 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. | ||
1005 | public class BSShapeConvexHull : BSShape | 1104 | public 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. | ||
1101 | public class BSShapeGImpact : BSShape | 1206 | public 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. | ||
1208 | public class BSShapeAvatar : BSShape | 1319 | public 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. |
166 | public class BulletHMapInfo | 166 | public 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 | |||
189 | public enum CollisionType | 190 | public 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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Linq; | ||
32 | using System.Text; | 31 | using System.Text; |
33 | 32 | ||
34 | using Nini.Config; | 33 | using Nini.Config; |
35 | 34 | ||
36 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
37 | using OpenSim.Region.Physics.BulletSPlugin; | 36 | using OpenSim.Region.Physics.Manager; |
38 | using OpenSim.Region.Physics.Meshing; | 37 | using OpenSim.Region.Physics.Meshing; |
39 | 38 | ||
39 | using OpenMetaverse; | ||
40 | |||
40 | namespace OpenSim.Region.Physics.BulletSPlugin.Tests | 41 | namespace 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | |||
33 | using NUnit.Framework; | ||
34 | using log4net; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Physics.BulletSPlugin; | ||
38 | using OpenSim.Region.Physics.Manager; | ||
39 | using OpenSim.Tests.Common; | ||
40 | |||
41 | using OpenMetaverse; | ||
42 | |||
43 | namespace OpenSim.Region.Physics.BulletSPlugin.Tests | ||
44 | { | ||
45 | [TestFixture] | ||
46 | public 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; |