aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs343
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;