diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 343 |
1 files changed, 110 insertions, 233 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index a19d6d7..7590d93 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -66,7 +66,7 @@ public sealed class BSPrim : PhysicsActor | |||
66 | private bool _isSelected; | 66 | private bool _isSelected; |
67 | private bool _isVolumeDetect; | 67 | private bool _isVolumeDetect; |
68 | private OMV.Vector3 _position; | 68 | private OMV.Vector3 _position; |
69 | private float _mass; | 69 | private float _mass; // the mass of this object |
70 | private float _density; | 70 | private float _density; |
71 | private OMV.Vector3 _force; | 71 | private OMV.Vector3 _force; |
72 | private OMV.Vector3 _velocity; | 72 | private OMV.Vector3 _velocity; |
@@ -89,14 +89,22 @@ public sealed class BSPrim : PhysicsActor | |||
89 | private bool _kinematic; | 89 | private bool _kinematic; |
90 | private float _buoyancy; | 90 | private float _buoyancy; |
91 | 91 | ||
92 | private BSPrim _parentPrim; | 92 | // Membership in a linkset is controlled by this class. |
93 | private List<BSPrim> _childrenPrims; | 93 | private BSLinkset _linkset; |
94 | public BSLinkset Linkset | ||
95 | { | ||
96 | get { return _linkset; } | ||
97 | set { _linkset = value; } | ||
98 | } | ||
94 | 99 | ||
95 | private int _subscribedEventsMs = 0; | 100 | private int _subscribedEventsMs = 0; |
96 | private int _nextCollisionOkTime = 0; | 101 | private int _nextCollisionOkTime = 0; |
97 | long _collidingStep; | 102 | long _collidingStep; |
98 | long _collidingGroundStep; | 103 | long _collidingGroundStep; |
99 | 104 | ||
105 | private BulletBody m_body; | ||
106 | public BulletBody Body { get { return m_body; } } | ||
107 | |||
100 | private BSDynamics _vehicle; | 108 | private BSDynamics _vehicle; |
101 | 109 | ||
102 | private OMV.Vector3 _PIDTarget; | 110 | private OMV.Vector3 _PIDTarget; |
@@ -130,14 +138,18 @@ public sealed class BSPrim : PhysicsActor | |||
130 | _friction = _scene.Params.defaultFriction; // TODO: compute based on object material | 138 | _friction = _scene.Params.defaultFriction; // TODO: compute based on object material |
131 | _density = _scene.Params.defaultDensity; // TODO: compute based on object material | 139 | _density = _scene.Params.defaultDensity; // TODO: compute based on object material |
132 | _restitution = _scene.Params.defaultRestitution; | 140 | _restitution = _scene.Params.defaultRestitution; |
133 | _parentPrim = null; // not a child or a parent | 141 | _linkset = new BSLinkset(_scene, this); // a linkset of one |
134 | _vehicle = new BSDynamics(this); // add vehicleness | 142 | _vehicle = new BSDynamics(this); // add vehicleness |
135 | _childrenPrims = new List<BSPrim>(); | ||
136 | _mass = CalculateMass(); | 143 | _mass = CalculateMass(); |
137 | // do the actual object creation at taint time | 144 | // do the actual object creation at taint time |
138 | _scene.TaintedObject(delegate() | 145 | _scene.TaintedObject(delegate() |
139 | { | 146 | { |
140 | RecreateGeomAndObject(); | 147 | RecreateGeomAndObject(); |
148 | |||
149 | // Get the pointer to the physical body for this object. | ||
150 | // At the moment, we're still letting BulletSim manage the creation and destruction | ||
151 | // of the object. Someday we'll move that into the C# code. | ||
152 | m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); | ||
141 | }); | 153 | }); |
142 | } | 154 | } |
143 | 155 | ||
@@ -153,16 +165,8 @@ public sealed class BSPrim : PhysicsActor | |||
153 | 165 | ||
154 | _scene.TaintedObject(delegate() | 166 | _scene.TaintedObject(delegate() |
155 | { | 167 | { |
156 | // undo any dependance with/on other objects | 168 | // Undo any links between me and any other object |
157 | if (_parentPrim != null) | 169 | _linkset = _linkset.RemoveMeFromLinkset(this); |
158 | { | ||
159 | // If I'm someone's child, tell them to forget about me. | ||
160 | _parentPrim.RemoveChildFromLinkset(this); | ||
161 | _parentPrim = null; | ||
162 | } | ||
163 | |||
164 | // make sure there are no possible children depending on me | ||
165 | UnlinkAllChildren(); | ||
166 | 170 | ||
167 | // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. | 171 | // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. |
168 | BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); | 172 | BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); |
@@ -179,7 +183,7 @@ public sealed class BSPrim : PhysicsActor | |||
179 | _scene.TaintedObject(delegate() | 183 | _scene.TaintedObject(delegate() |
180 | { | 184 | { |
181 | _mass = CalculateMass(); // changing size changes the mass | 185 | _mass = CalculateMass(); // changing size changes the mass |
182 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical); | 186 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); |
183 | RecreateGeomAndObject(); | 187 | RecreateGeomAndObject(); |
184 | }); | 188 | }); |
185 | } | 189 | } |
@@ -218,32 +222,8 @@ public sealed class BSPrim : PhysicsActor | |||
218 | BSPrim parent = obj as BSPrim; | 222 | BSPrim parent = obj as BSPrim; |
219 | DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); | 223 | DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); |
220 | DetailLog("{0},link,parent={1}", LocalID, obj.LocalID); | 224 | DetailLog("{0},link,parent={1}", LocalID, obj.LocalID); |
221 | // TODO: decide if this parent checking needs to happen at taint time | 225 | |
222 | if (_parentPrim == null) | 226 | _linkset = _linkset.AddMeToLinkset(this, parent); |
223 | { | ||
224 | if (parent != null) | ||
225 | { | ||
226 | // I don't have a parent so I am joining a linkset | ||
227 | parent.AddChildToLinkset(this); | ||
228 | } | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | // I already have a parent, is parenting changing? | ||
233 | if (parent != _parentPrim) | ||
234 | { | ||
235 | if (parent == null) | ||
236 | { | ||
237 | // we are being removed from a linkset | ||
238 | _parentPrim.RemoveChildFromLinkset(this); | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | // asking to reparent a prim should not happen | ||
243 | m_log.ErrorFormat("{0}: link(): Reparenting a prim. ", LogHeader); | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | return; | 227 | return; |
248 | } | 228 | } |
249 | 229 | ||
@@ -252,92 +232,28 @@ public sealed class BSPrim : PhysicsActor | |||
252 | // TODO: decide if this parent checking needs to happen at taint time | 232 | // TODO: decide if this parent checking needs to happen at taint time |
253 | // Race condition here: if link() and delink() in same simulation tick, the delink will not happen | 233 | // Race condition here: if link() and delink() in same simulation tick, the delink will not happen |
254 | DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, | 234 | DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, |
255 | (_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString())); | 235 | _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString()); |
256 | DetailLog("{0},delink,parent={1}", LocalID, (_parentPrim==null ? "NULL" : _parentPrim.LocalID.ToString())); | 236 | DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString()); |
257 | if (_parentPrim != null) | ||
258 | { | ||
259 | _parentPrim.RemoveChildFromLinkset(this); | ||
260 | } | ||
261 | return; | ||
262 | } | ||
263 | |||
264 | // I am the root of a linkset and a new child is being added | ||
265 | public void AddChildToLinkset(BSPrim pchild) | ||
266 | { | ||
267 | BSPrim child = pchild; | ||
268 | _scene.TaintedObject(delegate() | ||
269 | { | ||
270 | if (!_childrenPrims.Contains(child)) | ||
271 | { | ||
272 | DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID); | ||
273 | DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID); | ||
274 | _childrenPrims.Add(child); | ||
275 | child._parentPrim = this; // the child has gained a parent | ||
276 | // RecreateGeomAndObject(); // rebuild my shape with the new child added | ||
277 | LinkAChildToMe(pchild); // build the physical binding between me and the child | ||
278 | |||
279 | _mass = CalculateMass(); | ||
280 | } | ||
281 | }); | ||
282 | return; | ||
283 | } | ||
284 | |||
285 | // I am the root of a linkset and one of my children is being removed. | ||
286 | // Safe to call even if the child is not really in my linkset. | ||
287 | public void RemoveChildFromLinkset(BSPrim pchild) | ||
288 | { | ||
289 | BSPrim child = pchild; | ||
290 | _scene.TaintedObject(delegate() | ||
291 | { | ||
292 | if (_childrenPrims.Contains(child)) | ||
293 | { | ||
294 | DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); | ||
295 | DetailLog("{0},RemoveChildFromLinkset,child={1}", LocalID, pchild.LocalID); | ||
296 | _childrenPrims.Remove(child); | ||
297 | child._parentPrim = null; // the child has lost its parent | ||
298 | if (_childrenPrims.Count == 0) | ||
299 | { | ||
300 | // if the linkset is empty, make sure all linkages have been removed | ||
301 | UnlinkAllChildren(); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | // RecreateGeomAndObject(); // rebuild my shape with the child removed | ||
306 | UnlinkAChildFromMe(pchild); | ||
307 | } | ||
308 | |||
309 | _mass = CalculateMass(); | ||
310 | } | ||
311 | else | ||
312 | { | ||
313 | m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset"); | ||
314 | } | ||
315 | }); | ||
316 | return; | ||
317 | } | ||
318 | 237 | ||
319 | // return true if we are the root of a linkset (there are children to manage) | 238 | _linkset.RemoveMeFromLinkset(this); |
320 | public bool IsRootOfLinkset | 239 | return; |
321 | { | ||
322 | get { return (_parentPrim == null && _childrenPrims.Count != 0); } | ||
323 | } | 240 | } |
324 | 241 | ||
325 | // Set motion values to zero. | 242 | // Set motion values to zero. |
326 | // Do it to the properties so the values get set in the physics engine. | 243 | // Do it to the properties so the values get set in the physics engine. |
327 | // Push the setting of the values to the viewer. | 244 | // Push the setting of the values to the viewer. |
328 | // Called at taint time! | 245 | // Called at taint time! |
329 | private void ZeroMotion() | 246 | public void ZeroMotion() |
330 | { | 247 | { |
331 | _velocity = OMV.Vector3.Zero; | 248 | _velocity = OMV.Vector3.Zero; |
332 | _acceleration = OMV.Vector3.Zero; | 249 | _acceleration = OMV.Vector3.Zero; |
333 | _rotationalVelocity = OMV.Vector3.Zero; | 250 | _rotationalVelocity = OMV.Vector3.Zero; |
334 | 251 | ||
335 | // Zero some other properties directly into the physics engine | 252 | // Zero some other properties directly into the physics engine |
336 | IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID); | 253 | BulletSimAPI.SetVelocity2(Body.Ptr, OMV.Vector3.Zero); |
337 | BulletSimAPI.SetVelocity2(obj, OMV.Vector3.Zero); | 254 | BulletSimAPI.SetAngularVelocity2(Body.Ptr, OMV.Vector3.Zero); |
338 | BulletSimAPI.SetAngularVelocity2(obj, OMV.Vector3.Zero); | 255 | BulletSimAPI.SetInterpolation2(Body.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); |
339 | BulletSimAPI.SetInterpolation2(obj, OMV.Vector3.Zero, OMV.Vector3.Zero); | 256 | BulletSimAPI.ClearForces2(Body.Ptr); |
340 | BulletSimAPI.ClearForces2(obj); | ||
341 | } | 257 | } |
342 | 258 | ||
343 | public override void LockAngularMotion(OMV.Vector3 axis) | 259 | public override void LockAngularMotion(OMV.Vector3 axis) |
@@ -348,9 +264,10 @@ public sealed class BSPrim : PhysicsActor | |||
348 | 264 | ||
349 | public override OMV.Vector3 Position { | 265 | public override OMV.Vector3 Position { |
350 | get { | 266 | get { |
351 | // child prims move around based on their parent. Need to get the latest location | 267 | if (!_linkset.IsRoot(this)) |
352 | if (_parentPrim != null) | 268 | // child prims move around based on their parent. Need to get the latest location |
353 | _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); | 269 | _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); |
270 | |||
354 | // don't do the GetObjectPosition for root elements because this function is called a zillion times | 271 | // don't do the GetObjectPosition for root elements because this function is called a zillion times |
355 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); | 272 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); |
356 | return _position; | 273 | return _position; |
@@ -366,16 +283,31 @@ public sealed class BSPrim : PhysicsActor | |||
366 | } | 283 | } |
367 | } | 284 | } |
368 | 285 | ||
369 | // Return the effective mass of the object. Non-physical objects do not have mass. | 286 | // Return the effective mass of the object. |
370 | public override float Mass { | 287 | // If there are multiple items in the linkset, add them together for the root |
371 | get { | 288 | public override float Mass |
372 | if (IsPhysical) | 289 | { |
373 | return _mass; | 290 | get |
374 | else | 291 | { |
375 | return 0f; | 292 | return _linkset.LinksetMass; |
376 | } | 293 | } |
377 | } | 294 | } |
378 | 295 | ||
296 | // used when we only want this prim's mass and not the linkset thing | ||
297 | public float MassRaw { get { return _mass; } } | ||
298 | |||
299 | // Is this used? | ||
300 | public override OMV.Vector3 CenterOfMass | ||
301 | { | ||
302 | get { return _linkset.CenterOfMass; } | ||
303 | } | ||
304 | |||
305 | // Is this used? | ||
306 | public override OMV.Vector3 GeometricCenter | ||
307 | { | ||
308 | get { return _linkset.GeometricCenter; } | ||
309 | } | ||
310 | |||
379 | public override OMV.Vector3 Force { | 311 | public override OMV.Vector3 Force { |
380 | get { return _force; } | 312 | get { return _force; } |
381 | set { | 313 | set { |
@@ -383,7 +315,8 @@ public sealed class BSPrim : PhysicsActor | |||
383 | _scene.TaintedObject(delegate() | 315 | _scene.TaintedObject(delegate() |
384 | { | 316 | { |
385 | DetailLog("{0},SetForce,taint,force={1}", LocalID, _force); | 317 | DetailLog("{0},SetForce,taint,force={1}", LocalID, _force); |
386 | BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); | 318 | // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); |
319 | BulletSimAPI.SetObjectForce2(Body.Ptr, _force); | ||
387 | }); | 320 | }); |
388 | } | 321 | } |
389 | } | 322 | } |
@@ -407,8 +340,7 @@ public sealed class BSPrim : PhysicsActor | |||
407 | _scene.TaintedObject(delegate() | 340 | _scene.TaintedObject(delegate() |
408 | { | 341 | { |
409 | // Tell the physics engine to clear state | 342 | // Tell the physics engine to clear state |
410 | IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID); | 343 | BulletSimAPI.ClearForces2(this.Body.Ptr); |
411 | BulletSimAPI.ClearForces2(obj); | ||
412 | }); | 344 | }); |
413 | 345 | ||
414 | // make it so the scene will call us each tick to do vehicle things | 346 | // make it so the scene will call us each tick to do vehicle things |
@@ -420,7 +352,6 @@ public sealed class BSPrim : PhysicsActor | |||
420 | } | 352 | } |
421 | public override void VehicleFloatParam(int param, float value) | 353 | public override void VehicleFloatParam(int param, float value) |
422 | { | 354 | { |
423 | m_log.DebugFormat("{0} VehicleFloatParam. {1} <= {2}", LogHeader, param, value); | ||
424 | _scene.TaintedObject(delegate() | 355 | _scene.TaintedObject(delegate() |
425 | { | 356 | { |
426 | _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); | 357 | _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); |
@@ -428,7 +359,6 @@ public sealed class BSPrim : PhysicsActor | |||
428 | } | 359 | } |
429 | public override void VehicleVectorParam(int param, OMV.Vector3 value) | 360 | public override void VehicleVectorParam(int param, OMV.Vector3 value) |
430 | { | 361 | { |
431 | m_log.DebugFormat("{0} VehicleVectorParam. {1} <= {2}", LogHeader, param, value); | ||
432 | _scene.TaintedObject(delegate() | 362 | _scene.TaintedObject(delegate() |
433 | { | 363 | { |
434 | _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); | 364 | _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); |
@@ -436,7 +366,6 @@ public sealed class BSPrim : PhysicsActor | |||
436 | } | 366 | } |
437 | public override void VehicleRotationParam(int param, OMV.Quaternion rotation) | 367 | public override void VehicleRotationParam(int param, OMV.Quaternion rotation) |
438 | { | 368 | { |
439 | m_log.DebugFormat("{0} VehicleRotationParam. {1} <= {2}", LogHeader, param, rotation); | ||
440 | _scene.TaintedObject(delegate() | 369 | _scene.TaintedObject(delegate() |
441 | { | 370 | { |
442 | _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); | 371 | _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); |
@@ -444,7 +373,6 @@ public sealed class BSPrim : PhysicsActor | |||
444 | } | 373 | } |
445 | public override void VehicleFlags(int param, bool remove) | 374 | public override void VehicleFlags(int param, bool remove) |
446 | { | 375 | { |
447 | m_log.DebugFormat("{0} VehicleFlags. {1}. Remove={2}", LogHeader, param, remove); | ||
448 | _scene.TaintedObject(delegate() | 376 | _scene.TaintedObject(delegate() |
449 | { | 377 | { |
450 | _vehicle.ProcessVehicleFlags(param, remove); | 378 | _vehicle.ProcessVehicleFlags(param, remove); |
@@ -470,8 +398,6 @@ public sealed class BSPrim : PhysicsActor | |||
470 | return; | 398 | return; |
471 | } | 399 | } |
472 | 400 | ||
473 | public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } | ||
474 | public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } | ||
475 | public override OMV.Vector3 Velocity { | 401 | public override OMV.Vector3 Velocity { |
476 | get { return _velocity; } | 402 | get { return _velocity; } |
477 | set { | 403 | set { |
@@ -500,9 +426,9 @@ public sealed class BSPrim : PhysicsActor | |||
500 | } | 426 | } |
501 | public override OMV.Quaternion Orientation { | 427 | public override OMV.Quaternion Orientation { |
502 | get { | 428 | get { |
503 | if (_parentPrim != null) | 429 | if (!_linkset.IsRoot(this)) |
504 | { | 430 | { |
505 | // children move around because tied to parent. Get a fresh value. | 431 | // Children move around because tied to parent. Get a fresh value. |
506 | _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); | 432 | _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); |
507 | } | 433 | } |
508 | return _orientation; | 434 | return _orientation; |
@@ -552,14 +478,16 @@ public sealed class BSPrim : PhysicsActor | |||
552 | private void SetObjectDynamic() | 478 | private void SetObjectDynamic() |
553 | { | 479 | { |
554 | // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); | 480 | // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); |
555 | // non-physical things work best with a mass of zero | 481 | |
556 | if (!IsStatic) | 482 | RecreateGeomAndObject(); |
557 | { | 483 | |
558 | _mass = CalculateMass(); | 484 | float mass = _mass; |
559 | RecreateGeomAndObject(); | 485 | // Bullet wants static objects have a mass of zero |
560 | } | 486 | if (IsStatic) |
561 | DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass); | 487 | mass = 0f; |
562 | BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass); | 488 | |
489 | DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); | ||
490 | BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); | ||
563 | } | 491 | } |
564 | 492 | ||
565 | // prims don't fly | 493 | // prims don't fly |
@@ -1001,6 +929,9 @@ public sealed class BSPrim : PhysicsActor | |||
1001 | 929 | ||
1002 | returnMass = _density * volume; | 930 | returnMass = _density * volume; |
1003 | 931 | ||
932 | /* | ||
933 | * This change means each object keeps its own mass and the Mass property | ||
934 | * will return the sum if we're part of a linkset. | ||
1004 | if (IsRootOfLinkset) | 935 | if (IsRootOfLinkset) |
1005 | { | 936 | { |
1006 | foreach (BSPrim prim in _childrenPrims) | 937 | foreach (BSPrim prim in _childrenPrims) |
@@ -1008,6 +939,7 @@ public sealed class BSPrim : PhysicsActor | |||
1008 | returnMass += prim.CalculateMass(); | 939 | returnMass += prim.CalculateMass(); |
1009 | } | 940 | } |
1010 | } | 941 | } |
942 | */ | ||
1011 | 943 | ||
1012 | if (returnMass <= 0) | 944 | if (returnMass <= 0) |
1013 | returnMass = 0.0001f; | 945 | returnMass = 0.0001f; |
@@ -1023,9 +955,11 @@ public sealed class BSPrim : PhysicsActor | |||
1023 | // The objects needs a hull if it's physical otherwise a mesh is enough | 955 | // The objects needs a hull if it's physical otherwise a mesh is enough |
1024 | // No locking here because this is done when we know physics is not simulating | 956 | // No locking here because this is done when we know physics is not simulating |
1025 | // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used | 957 | // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used |
1026 | private void CreateGeom(bool forceRebuild) | 958 | // Returns 'true' if the geometry was rebuilt |
959 | private bool CreateGeom(bool forceRebuild) | ||
1027 | { | 960 | { |
1028 | // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. | 961 | // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. |
962 | bool ret = false; | ||
1029 | if (!_scene.NeedsMeshing(_pbs)) | 963 | if (!_scene.NeedsMeshing(_pbs)) |
1030 | { | 964 | { |
1031 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) | 965 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) |
@@ -1033,18 +967,26 @@ public sealed class BSPrim : PhysicsActor | |||
1033 | if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) | 967 | if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) |
1034 | { | 968 | { |
1035 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); | 969 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); |
1036 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; | 970 | if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE) |
1037 | DetailLog("{0},CreateGeom,sphere", LocalID); | 971 | { |
1038 | // Bullet native objects are scaled by the Bullet engine so pass the size in | 972 | DetailLog("{0},CreateGeom,sphere", LocalID); |
1039 | _scale = _size; | 973 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; |
974 | ret = true; | ||
975 | // Bullet native objects are scaled by the Bullet engine so pass the size in | ||
976 | _scale = _size; | ||
977 | } | ||
1040 | } | 978 | } |
1041 | } | 979 | } |
1042 | else | 980 | else |
1043 | { | 981 | { |
1044 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); | 982 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); |
1045 | DetailLog("{0},CreateGeom,box", LocalID); | 983 | if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX) |
1046 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; | 984 | { |
1047 | _scale = _size; | 985 | DetailLog("{0},CreateGeom,box", LocalID); |
986 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; | ||
987 | ret = true; | ||
988 | _scale = _size; | ||
989 | } | ||
1048 | } | 990 | } |
1049 | } | 991 | } |
1050 | else | 992 | else |
@@ -1056,6 +998,7 @@ public sealed class BSPrim : PhysicsActor | |||
1056 | // physical objects require a hull for interaction. | 998 | // physical objects require a hull for interaction. |
1057 | // This will create the mesh if it doesn't already exist | 999 | // This will create the mesh if it doesn't already exist |
1058 | CreateGeomHull(); | 1000 | CreateGeomHull(); |
1001 | ret = true; | ||
1059 | } | 1002 | } |
1060 | } | 1003 | } |
1061 | else | 1004 | else |
@@ -1064,9 +1007,11 @@ public sealed class BSPrim : PhysicsActor | |||
1064 | { | 1007 | { |
1065 | // Static (non-physical) objects only need a mesh for bumping into | 1008 | // Static (non-physical) objects only need a mesh for bumping into |
1066 | CreateGeomMesh(); | 1009 | CreateGeomMesh(); |
1010 | ret = true; | ||
1067 | } | 1011 | } |
1068 | } | 1012 | } |
1069 | } | 1013 | } |
1014 | return ret; | ||
1070 | } | 1015 | } |
1071 | 1016 | ||
1072 | // No locking here because this is done when we know physics is not simulating | 1017 | // No locking here because this is done when we know physics is not simulating |
@@ -1251,20 +1196,18 @@ public sealed class BSPrim : PhysicsActor | |||
1251 | // No locking here because this is done when the physics engine is not simulating | 1196 | // No locking here because this is done when the physics engine is not simulating |
1252 | private void CreateObject() | 1197 | private void CreateObject() |
1253 | { | 1198 | { |
1254 | if (IsRootOfLinkset) | 1199 | // this routine is called when objects are rebuilt. |
1255 | { | 1200 | |
1256 | // Create a linkset around this object | 1201 | // the mesh or hull must have already been created in Bullet |
1257 | CreateLinkset(); | 1202 | ShapeData shape; |
1258 | } | 1203 | FillShapeInfo(out shape); |
1259 | else | 1204 | // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); |
1260 | { | 1205 | BulletSimAPI.CreateObject(_scene.WorldID, shape); |
1261 | // simple object | 1206 | // the CreateObject() may have recreated the rigid body. Make sure we have the latest. |
1262 | // the mesh or hull must have already been created in Bullet | 1207 | m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID); |
1263 | ShapeData shape; | 1208 | |
1264 | FillShapeInfo(out shape); | 1209 | // The root object could have been recreated. Make sure everything linksety is up to date. |
1265 | // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); | 1210 | _linkset.RefreshLinkset(this); |
1266 | BulletSimAPI.CreateObject(_scene.WorldID, shape); | ||
1267 | } | ||
1268 | } | 1211 | } |
1269 | 1212 | ||
1270 | // Copy prim's info into the BulletSim shape description structure | 1213 | // Copy prim's info into the BulletSim shape description structure |
@@ -1276,7 +1219,7 @@ public sealed class BSPrim : PhysicsActor | |||
1276 | shape.Rotation = _orientation; | 1219 | shape.Rotation = _orientation; |
1277 | shape.Velocity = _velocity; | 1220 | shape.Velocity = _velocity; |
1278 | shape.Scale = _scale; | 1221 | shape.Scale = _scale; |
1279 | shape.Mass = Mass; | 1222 | shape.Mass = _isPhysical ? _mass : 0f; |
1280 | shape.Buoyancy = _buoyancy; | 1223 | shape.Buoyancy = _buoyancy; |
1281 | shape.HullKey = _hullKey; | 1224 | shape.HullKey = _hullKey; |
1282 | shape.MeshKey = _meshKey; | 1225 | shape.MeshKey = _meshKey; |
@@ -1286,72 +1229,6 @@ public sealed class BSPrim : PhysicsActor | |||
1286 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; | 1229 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; |
1287 | } | 1230 | } |
1288 | 1231 | ||
1289 | #region Linkset creation and destruction | ||
1290 | |||
1291 | // Create the linkset by putting constraints between the objects of the set so they cannot move | ||
1292 | // relative to each other. | ||
1293 | void CreateLinkset() | ||
1294 | { | ||
1295 | DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); | ||
1296 | |||
1297 | // remove any constraints that might be in place | ||
1298 | DebugLog("{0}: CreateLinkset: RemoveConstraints between me and any children", LogHeader, LocalID); | ||
1299 | BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID); | ||
1300 | |||
1301 | // create constraints between the root prim and each of the children | ||
1302 | foreach (BSPrim prim in _childrenPrims) | ||
1303 | { | ||
1304 | LinkAChildToMe(prim); | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1308 | // Create a constraint between me (root of linkset) and the passed prim (the child). | ||
1309 | // Called at taint time! | ||
1310 | private void LinkAChildToMe(BSPrim childPrim) | ||
1311 | { | ||
1312 | // Zero motion for children so they don't interpolate | ||
1313 | childPrim.ZeroMotion(); | ||
1314 | |||
1315 | // relative position normalized to the root prim | ||
1316 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation); | ||
1317 | OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation; | ||
1318 | |||
1319 | // relative rotation of the child to the parent | ||
1320 | OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation; | ||
1321 | |||
1322 | // create a constraint that allows no freedom of movement between the two objects | ||
1323 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||
1324 | DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); | ||
1325 | DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID); | ||
1326 | BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, childPrim.LocalID, | ||
1327 | childRelativePosition, | ||
1328 | childRelativeRotation, | ||
1329 | OMV.Vector3.Zero, | ||
1330 | OMV.Quaternion.Identity, | ||
1331 | OMV.Vector3.Zero, OMV.Vector3.Zero, | ||
1332 | OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
1333 | } | ||
1334 | |||
1335 | // Remove linkage between myself and a particular child | ||
1336 | // Called at taint time! | ||
1337 | private void UnlinkAChildFromMe(BSPrim childPrim) | ||
1338 | { | ||
1339 | DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}", | ||
1340 | LogHeader, LocalID, childPrim.LocalID); | ||
1341 | DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID); | ||
1342 | BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID); | ||
1343 | } | ||
1344 | |||
1345 | // Remove linkage between myself and any possible children I might have | ||
1346 | // Called at taint time! | ||
1347 | private void UnlinkAllChildren() | ||
1348 | { | ||
1349 | DebugLog("{0}: UnlinkAllChildren:", LogHeader); | ||
1350 | DetailLog("{0},UnlinkAllChildren,taint", LocalID); | ||
1351 | BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID); | ||
1352 | } | ||
1353 | |||
1354 | #endregion // Linkset creation and destruction | ||
1355 | 1232 | ||
1356 | // Rebuild the geometry and object. | 1233 | // Rebuild the geometry and object. |
1357 | // This is called when the shape changes so we need to recreate the mesh/hull. | 1234 | // This is called when the shape changes so we need to recreate the mesh/hull. |
@@ -1429,7 +1306,7 @@ public sealed class BSPrim : PhysicsActor | |||
1429 | // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. | 1306 | // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. |
1430 | 1307 | ||
1431 | // Updates only for individual prims and for the root object of a linkset. | 1308 | // Updates only for individual prims and for the root object of a linkset. |
1432 | if (_parentPrim == null) | 1309 | if (_linkset.IsRoot(this)) |
1433 | { | 1310 | { |
1434 | // Assign to the local variables so the normal set action does not happen | 1311 | // Assign to the local variables so the normal set action does not happen |
1435 | _position = entprop.Position; | 1312 | _position = entprop.Position; |