diff options
author | Robert Adams | 2012-12-16 21:18:32 -0800 |
---|---|---|
committer | Robert Adams | 2012-12-16 21:19:13 -0800 |
commit | 2b8efa24dd816fda23fe3aed5822af1d50febf5d (patch) | |
tree | 287352bc66cf34ce25ee86a59099af43d2d23cb4 /OpenSim | |
parent | BulletSim: add even more to the TODO list. (diff) | |
download | opensim-SC_OLD-2b8efa24dd816fda23fe3aed5822af1d50febf5d.zip opensim-SC_OLD-2b8efa24dd816fda23fe3aed5822af1d50febf5d.tar.gz opensim-SC_OLD-2b8efa24dd816fda23fe3aed5822af1d50febf5d.tar.bz2 opensim-SC_OLD-2b8efa24dd816fda23fe3aed5822af1d50febf5d.tar.xz |
BulletSim: add parameter to UpdateProperties call into the linkset so changes from the physics engine can be differentiated from changes made by the user. This eliminates a linkset rebuild loop. Also add logic to not rebuild or freak out when the object/linkset crosses a terrain boundry.
Diffstat (limited to 'OpenSim')
6 files changed, 65 insertions, 36 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 2486be5..2017fa5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -252,8 +252,9 @@ public abstract class BSLinkset | |||
252 | 252 | ||
253 | // Called when a parameter update comes from the physics engine for any object | 253 | // Called when a parameter update comes from the physics engine for any object |
254 | // of the linkset is received. | 254 | // of the linkset is received. |
255 | // Passed flag is update came from physics engine (true) or the user (false). | ||
255 | // Called at taint-time!! | 256 | // Called at taint-time!! |
256 | public abstract void UpdateProperties(BSPhysObject physObject); | 257 | public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate); |
257 | 258 | ||
258 | // Routine used when rebuilding the body of the root of the linkset | 259 | // Routine used when rebuilding the body of the root of the linkset |
259 | // Destroy all the constraints have have been made to root. | 260 | // Destroy all the constraints have have been made to root. |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8359607..4d4f712 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -28,6 +28,8 @@ using System; | |||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Text; | 29 | using System.Text; |
30 | 30 | ||
31 | using OpenSim.Framework; | ||
32 | |||
31 | using OMV = OpenMetaverse; | 33 | using OMV = OpenMetaverse; |
32 | 34 | ||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | 35 | namespace OpenSim.Region.Physics.BulletSPlugin |
@@ -87,25 +89,22 @@ public sealed class BSLinksetCompound : BSLinkset | |||
87 | // its internal properties. | 89 | // its internal properties. |
88 | public override void Refresh(BSPhysObject requestor) | 90 | public override void Refresh(BSPhysObject requestor) |
89 | { | 91 | { |
90 | if (!IsRoot(requestor)) | ||
91 | { | ||
92 | } | ||
93 | // Something changed so do the rebuilding thing | 92 | // Something changed so do the rebuilding thing |
94 | InternalRefresh(requestor); | 93 | // ScheduleRebuild(); |
95 | } | 94 | } |
96 | 95 | ||
97 | // Schedule a refresh to happen after all the other taint processing. | 96 | // Schedule a refresh to happen after all the other taint processing. |
98 | private void InternalRefresh(BSPhysObject requestor) | 97 | private void ScheduleRebuild() |
99 | { | 98 | { |
100 | DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}", | 99 | DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", |
101 | LinksetRoot.LocalID, requestor.LocalID, Rebuilding); | 100 | LinksetRoot.LocalID, Rebuilding); |
102 | // When rebuilding, it is possible to set properties that would normally require a rebuild. | 101 | // When rebuilding, it is possible to set properties that would normally require a rebuild. |
103 | // If already rebuilding, don't request another rebuild. | 102 | // If already rebuilding, don't request another rebuild. |
104 | if (!Rebuilding) | 103 | if (!Rebuilding) |
105 | { | 104 | { |
106 | PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() | 105 | PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() |
107 | { | 106 | { |
108 | if (IsRoot(requestor) && HasAnyChildren) | 107 | if (HasAnyChildren) |
109 | RecomputeLinksetCompound(); | 108 | RecomputeLinksetCompound(); |
110 | }); | 109 | }); |
111 | } | 110 | } |
@@ -125,8 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
125 | { | 124 | { |
126 | // The root is going dynamic. Make sure mass is properly set. | 125 | // The root is going dynamic. Make sure mass is properly set. |
127 | m_mass = ComputeLinksetMass(); | 126 | m_mass = ComputeLinksetMass(); |
128 | if (HasAnyChildren) | 127 | ScheduleRebuild(); |
129 | InternalRefresh(LinksetRoot); | ||
130 | } | 128 | } |
131 | else | 129 | else |
132 | { | 130 | { |
@@ -155,8 +153,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
155 | DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); | 153 | DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); |
156 | if (IsRoot(child)) | 154 | if (IsRoot(child)) |
157 | { | 155 | { |
158 | if (HasAnyChildren) | 156 | ScheduleRebuild(); |
159 | InternalRefresh(LinksetRoot); | ||
160 | } | 157 | } |
161 | else | 158 | else |
162 | { | 159 | { |
@@ -172,10 +169,21 @@ public sealed class BSLinksetCompound : BSLinkset | |||
172 | return ret; | 169 | return ret; |
173 | } | 170 | } |
174 | 171 | ||
175 | // Called at taint-time!! | 172 | public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) |
176 | public override void UpdateProperties(BSPhysObject updated) | ||
177 | { | 173 | { |
178 | // Nothing to do for compound linksets on property updates | 174 | // The user moving a child around requires the rebuilding of the linkset compound shape |
175 | // One problem is this happens when a border is crossed -- the simulator implementation | ||
176 | // is to store the position into the group which causes the move of the object | ||
177 | // but it also means all the child positions get updated. | ||
178 | // What would cause an unnecessary rebuild so we make sure the linkset is in a | ||
179 | // region before bothering to do a rebuild. | ||
180 | if (!IsRoot(updated) | ||
181 | && !physicalUpdate | ||
182 | && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) | ||
183 | { | ||
184 | updated.LinksetInfo = null; | ||
185 | ScheduleRebuild(); | ||
186 | } | ||
179 | } | 187 | } |
180 | 188 | ||
181 | // Routine called when rebuilding the body of some member of the linkset. | 189 | // Routine called when rebuilding the body of some member of the linkset. |
@@ -257,8 +265,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
257 | 265 | ||
258 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); | 266 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); |
259 | 267 | ||
260 | // Cause constraints and assorted properties to be recomputed before the next simulation step. | 268 | // Rebuild the compound shape with the new child shape included |
261 | InternalRefresh(LinksetRoot); | 269 | ScheduleRebuild(); |
262 | } | 270 | } |
263 | return; | 271 | return; |
264 | } | 272 | } |
@@ -285,8 +293,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
285 | } | 293 | } |
286 | else | 294 | else |
287 | { | 295 | { |
288 | // Schedule a rebuild of the linkset before the next simulation tick. | 296 | // Rebuild the compound shape with the child removed |
289 | InternalRefresh(LinksetRoot); | 297 | ScheduleRebuild(); |
290 | } | 298 | } |
291 | } | 299 | } |
292 | return; | 300 | return; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 7076ab4..8c36c31 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 | } | 78 | } |
79 | 79 | ||
80 | // Called at taint-time!! | 80 | // Called at taint-time!! |
81 | public override void UpdateProperties(BSPhysObject updated) | 81 | public override void UpdateProperties(BSPhysObject updated, bool inTaintTime) |
82 | { | 82 | { |
83 | // Nothing to do for constraints on property updates | 83 | // Nothing to do for constraints on property updates |
84 | } | 84 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 6539b43..92a5f2f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -214,7 +214,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
214 | { | 214 | { |
215 | bool ret = true; | 215 | bool ret = true; |
216 | // If the 'no collision' call, force it to happen right now so quick collision_end | 216 | // If the 'no collision' call, force it to happen right now so quick collision_end |
217 | bool force = CollisionCollection.Count == 0; | 217 | bool force = (CollisionCollection.Count == 0); |
218 | 218 | ||
219 | // throttle the collisions to the number of milliseconds specified in the subscription | 219 | // throttle the collisions to the number of milliseconds specified in the subscription |
220 | if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) | 220 | if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) |
@@ -232,8 +232,10 @@ public abstract class BSPhysObject : PhysicsActor | |||
232 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); | 232 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); |
233 | base.SendCollisionUpdate(CollisionCollection); | 233 | base.SendCollisionUpdate(CollisionCollection); |
234 | 234 | ||
235 | // The collisionCollection structure is passed around in the simulator. | 235 | // The CollisionCollection instance is passed around in the simulator. |
236 | // Make sure we don't have a handle to that one and that a new one is used for next time. | 236 | // Make sure we don't have a handle to that one and that a new one is used for next time. |
237 | // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, | ||
238 | // a race condition is created for the other users of this instance. | ||
237 | CollisionCollection = new CollisionEventUpdate(); | 239 | CollisionCollection = new CollisionEventUpdate(); |
238 | } | 240 | } |
239 | return ret; | 241 | return ret; |
@@ -251,7 +253,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
251 | 253 | ||
252 | PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() | 254 | PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() |
253 | { | 255 | { |
254 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | 256 | if (PhysBody.HasPhysicalBody) |
257 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
255 | }); | 258 | }); |
256 | } | 259 | } |
257 | else | 260 | else |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 53be2e3..758d92b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -300,6 +300,10 @@ public sealed class BSPrim : BSPhysObject | |||
300 | } | 300 | } |
301 | _position = value; | 301 | _position = value; |
302 | PositionSanityCheck(false); | 302 | PositionSanityCheck(false); |
303 | |||
304 | // A linkset might need to know if a component information changed. | ||
305 | Linkset.UpdateProperties(this, false); | ||
306 | |||
303 | PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() | 307 | PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() |
304 | { | 308 | { |
305 | DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 309 | DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
@@ -329,6 +333,14 @@ public sealed class BSPrim : BSPhysObject | |||
329 | { | 333 | { |
330 | bool ret = false; | 334 | bool ret = false; |
331 | 335 | ||
336 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | ||
337 | { | ||
338 | // The physical object is out of the known/simulated area. | ||
339 | // Upper levels of code will handle the transition to other areas so, for | ||
340 | // the time, we just ignore the position. | ||
341 | return ret; | ||
342 | } | ||
343 | |||
332 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); | 344 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); |
333 | OMV.Vector3 upForce = OMV.Vector3.Zero; | 345 | OMV.Vector3 upForce = OMV.Vector3.Zero; |
334 | if (RawPosition.Z < terrainHeight) | 346 | if (RawPosition.Z < terrainHeight) |
@@ -352,8 +364,6 @@ public sealed class BSPrim : BSPhysObject | |||
352 | } | 364 | } |
353 | } | 365 | } |
354 | 366 | ||
355 | // TODO: check for out of bounds | ||
356 | |||
357 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. | 367 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. |
358 | // TODO: This should be intergrated with a geneal physics action mechanism. | 368 | // TODO: This should be intergrated with a geneal physics action mechanism. |
359 | // TODO: This should be moderated with PID'ness. | 369 | // TODO: This should be moderated with PID'ness. |
@@ -567,7 +577,10 @@ public sealed class BSPrim : BSPhysObject | |||
567 | if (_orientation == value) | 577 | if (_orientation == value) |
568 | return; | 578 | return; |
569 | _orientation = value; | 579 | _orientation = value; |
570 | // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? | 580 | |
581 | // A linkset might need to know if a component information changed. | ||
582 | Linkset.UpdateProperties(this, false); | ||
583 | |||
571 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() | 584 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() |
572 | { | 585 | { |
573 | if (PhysBody.HasPhysicalBody) | 586 | if (PhysBody.HasPhysicalBody) |
@@ -1432,14 +1445,14 @@ public sealed class BSPrim : BSPhysObject | |||
1432 | entprop.Velocity = _velocity; | 1445 | entprop.Velocity = _velocity; |
1433 | } | 1446 | } |
1434 | 1447 | ||
1435 | // remember the current and last set values | ||
1436 | LastEntityProperties = CurrentEntityProperties; | ||
1437 | CurrentEntityProperties = entprop; | ||
1438 | |||
1439 | OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG | 1448 | OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG |
1440 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", | 1449 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", |
1441 | LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); | 1450 | LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); |
1442 | 1451 | ||
1452 | // remember the current and last set values | ||
1453 | LastEntityProperties = CurrentEntityProperties; | ||
1454 | CurrentEntityProperties = entprop; | ||
1455 | |||
1443 | base.RequestPhysicsterseUpdate(); | 1456 | base.RequestPhysicsterseUpdate(); |
1444 | } | 1457 | } |
1445 | /* | 1458 | /* |
@@ -1453,7 +1466,7 @@ public sealed class BSPrim : BSPhysObject | |||
1453 | */ | 1466 | */ |
1454 | 1467 | ||
1455 | // The linkset implimentation might want to know about this. | 1468 | // The linkset implimentation might want to know about this. |
1456 | Linkset.UpdateProperties(this); | 1469 | Linkset.UpdateProperties(this, true); |
1457 | } | 1470 | } |
1458 | } | 1471 | } |
1459 | } | 1472 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index ac99777..7b44574 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -517,8 +517,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
517 | out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); | 517 | out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); |
518 | 518 | ||
519 | if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); | 519 | if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); |
520 | DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", | 520 | DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", |
521 | DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); | 521 | DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, |
522 | updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); | ||
522 | if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG | 523 | if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG |
523 | } | 524 | } |
524 | catch (Exception e) | 525 | catch (Exception e) |
@@ -573,6 +574,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
573 | 574 | ||
574 | // Objects that are done colliding are removed from the ObjectsWithCollisions list. | 575 | // Objects that are done colliding are removed from the ObjectsWithCollisions list. |
575 | // Not done above because it is inside an iteration of ObjectWithCollisions. | 576 | // Not done above because it is inside an iteration of ObjectWithCollisions. |
577 | // This complex collision processing is required to create an empty collision | ||
578 | // event call after all collisions have happened on an object. This enables | ||
579 | // the simulator to generate the 'collision end' event. | ||
576 | if (ObjectsWithNoMoreCollisions.Count > 0) | 580 | if (ObjectsWithNoMoreCollisions.Count > 0) |
577 | { | 581 | { |
578 | foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) | 582 | foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) |
@@ -597,7 +601,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
597 | 601 | ||
598 | ProcessPostStepTaints(); | 602 | ProcessPostStepTaints(); |
599 | 603 | ||
600 | // This causes the unmanaged code to output ALL the values found in ALL the objects in the world. | 604 | // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. |
601 | // Only enable this in a limited test world with few objects. | 605 | // Only enable this in a limited test world with few objects. |
602 | // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG | 606 | // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG |
603 | 607 | ||