diff options
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 35 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 26 |
2 files changed, 36 insertions, 25 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index ad8024c..5a1b5c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -319,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
319 | // Constraint linksets are rebuilt every time. | 319 | // Constraint linksets are rebuilt every time. |
320 | // Note that this works for rebuilding just the root after a linkset is taken apart. | 320 | // Note that this works for rebuilding just the root after a linkset is taken apart. |
321 | // Called at taint time!! | 321 | // Called at taint time!! |
322 | private bool disableCOM = true; // disable until we get this debugged | ||
322 | private void RecomputeLinksetCompound() | 323 | private void RecomputeLinksetCompound() |
323 | { | 324 | { |
324 | try | 325 | try |
@@ -331,15 +332,26 @@ public sealed class BSLinksetCompound : BSLinkset | |||
331 | 332 | ||
332 | // The center of mass for the linkset is the geometric center of the group. | 333 | // The center of mass for the linkset is the geometric center of the group. |
333 | // Compute a displacement for each component so it is relative to the center-of-mass. | 334 | // Compute a displacement for each component so it is relative to the center-of-mass. |
334 | OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter(); | 335 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass |
335 | OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; | 336 | OMV.Vector3 centerOfMass; |
337 | OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; | ||
338 | if (disableCOM) // DEBUG DEBUG | ||
339 | { // DEBUG DEBUG | ||
340 | centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG | ||
341 | LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; | ||
342 | } // DEBUG DEBUG | ||
343 | else | ||
344 | { | ||
345 | centerOfMass = ComputeLinksetGeometricCenter(); | ||
346 | centerDisplacement = centerOfMass - LinksetRoot.RawPosition; | ||
336 | 347 | ||
337 | // Since we're displacing the center of the shape, we need to move the body in the world | 348 | // Since we're displacing the center of the shape, we need to move the body in the world |
338 | LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation; | 349 | LinksetRoot.PositionDisplacement = centerDisplacement; |
339 | 350 | ||
340 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); | 351 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); |
341 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", | 352 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", |
342 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); | 353 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); |
354 | } | ||
343 | 355 | ||
344 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", | 356 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", |
345 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); | 357 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); |
@@ -357,14 +369,15 @@ public sealed class BSLinksetCompound : BSLinkset | |||
357 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | 369 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; |
358 | if (lci == null) | 370 | if (lci == null) |
359 | { | 371 | { |
360 | // Each child position and rotation is given relative to the root. | 372 | // Each child position and rotation is given relative to the center-of-mass. |
361 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | 373 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); |
362 | OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; | 374 | OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; |
375 | OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; | ||
363 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | 376 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; |
364 | 377 | ||
365 | // Save relative position for recomputing child's world position after moving linkset. | 378 | // Save relative position for recomputing child's world position after moving linkset. |
366 | lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot); | 379 | lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); |
367 | lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement; | 380 | lci.OffsetFromRoot = displacementFromRoot; |
368 | cPrim.LinksetInfo = lci; | 381 | cPrim.LinksetInfo = lci; |
369 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | 382 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); |
370 | } | 383 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 003dc54..e5f7ab7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -297,7 +297,7 @@ public sealed class BSPrim : BSPhysObject | |||
297 | */ | 297 | */ |
298 | 298 | ||
299 | // don't do the GetObjectPosition for root elements because this function is called a zillion times. | 299 | // don't do the GetObjectPosition for root elements because this function is called a zillion times. |
300 | // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); | 300 | // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; |
301 | return _position; | 301 | return _position; |
302 | } | 302 | } |
303 | set { | 303 | set { |
@@ -362,7 +362,7 @@ public sealed class BSPrim : BSPhysObject | |||
362 | { | 362 | { |
363 | bool ret = false; | 363 | bool ret = false; |
364 | 364 | ||
365 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 365 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
366 | { | 366 | { |
367 | // The physical object is out of the known/simulated area. | 367 | // The physical object is out of the known/simulated area. |
368 | // Upper levels of code will handle the transition to other areas so, for | 368 | // Upper levels of code will handle the transition to other areas so, for |
@@ -376,8 +376,11 @@ public sealed class BSPrim : BSPhysObject | |||
376 | { | 376 | { |
377 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 377 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
378 | float targetHeight = terrainHeight + (Size.Z / 2f); | 378 | float targetHeight = terrainHeight + (Size.Z / 2f); |
379 | // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. | 379 | // If the object is below ground it just has to be moved up because pushing will |
380 | upForce.Z = (terrainHeight - RawPosition.Z) * 1f; | 380 | // not get it through the terrain |
381 | _position.Z = targetHeight; | ||
382 | if (!inTaintTime) | ||
383 | ForcePosition = _position; | ||
381 | ret = true; | 384 | ret = true; |
382 | } | 385 | } |
383 | 386 | ||
@@ -389,20 +392,15 @@ public sealed class BSPrim : BSPhysObject | |||
389 | { | 392 | { |
390 | // Upforce proportional to the distance away from the water. Correct the error in 1 sec. | 393 | // Upforce proportional to the distance away from the water. Correct the error in 1 sec. |
391 | upForce.Z = (waterHeight - RawPosition.Z) * 1f; | 394 | upForce.Z = (waterHeight - RawPosition.Z) * 1f; |
395 | |||
396 | // Apply upforce and overcome gravity. | ||
397 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; | ||
398 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
399 | AddForce(correctionForce, false, inTaintTime); | ||
392 | ret = true; | 400 | ret = true; |
393 | } | 401 | } |
394 | } | 402 | } |
395 | 403 | ||
396 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. | ||
397 | // TODO: This should be intergrated with a geneal physics action mechanism. | ||
398 | // TODO: This should be moderated with PID'ness. | ||
399 | if (ret) | ||
400 | { | ||
401 | // Apply upforce and overcome gravity. | ||
402 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; | ||
403 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
404 | AddForce(correctionForce, false, inTaintTime); | ||
405 | } | ||
406 | return ret; | 404 | return ret; |
407 | } | 405 | } |
408 | 406 | ||