Skip to content

Commit e8323d7

Browse files
committed
Major rewrite of the constraints. Instead of using two frames that are defined independently, each constraint defines a single frame relative to the object it is attached to and the other frame is calculated for the other object.
Fixed problems with order of creation and destruction of constraints. Rigid bodies must exist and be added to the physics world before constraints are added.
1 parent afb01f9 commit e8323d7

25 files changed

Lines changed: 512 additions & 357 deletions
Binary file not shown.

UnityProject/Assets/BulletUnity/Examples/Scenes/Constraints/Constraints.unity.meta

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Binary file not shown.

UnityProject/Assets/BulletUnity/Scripts/BCollisionObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ protected virtual void RemoveObjectFromBulletWorld()
141141
BPhysicsWorld.Get().RemoveCollisionObject(m_collisionObject);
142142
}
143143

144-
protected virtual void Start()
144+
internal virtual void Start()
145145
{
146146
m_startHasBeenCalled = true;
147147
AddObjectToBulletWorld();

UnityProject/Assets/BulletUnity/Scripts/BCollisionObject.cs.meta

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnityProject/Assets/BulletUnity/Scripts/BGameObjectMotionState.cs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,34 +34,6 @@ public override void GetWorldTransform(out Matrix worldTrans) {
3434

3535
//Bullet calls this so I can copy bullet data to unity
3636
public override void SetWorldTransform(ref Matrix m) {
37-
/*
38-
BulletSharp.Math.Vector3 pos = m.Origin;
39-
UnityEngine.Quaternion q = new UnityEngine.Quaternion();
40-
q.w = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2;
41-
q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2;
42-
q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2;
43-
q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2;
44-
q.x *= Mathf.Sign(q.x * (m[1, 2] - m[2, 1]));
45-
q.y *= Mathf.Sign(q.y * (m[2, 0] - m[0, 2]));
46-
q.z *= Mathf.Sign(q.z * (m[0, 1] - m[1, 2]));
47-
*/
48-
49-
//todo not very efficient
50-
/*
51-
Matrix4x4 mu = m.ToUnity();
52-
UnityEngine.Vector3 p = BSExtensionMethods.ExtractTranslationFromMatrix(ref mu);
53-
UnityEngine.Quaternion q = BSExtensionMethods.ExtractRotationFromMatrix(ref mu);
54-
UnityEngine.Vector3 sc = BSExtensionMethods.ExtractScaleFromMatrix(ref mu);
55-
56-
UnityEngine.Vector3 p1 = BSExtensionMethods.ExtractTranslationFromMatrix(ref m);
57-
UnityEngine.Quaternion q1 = BSExtensionMethods.ExtractRotationFromMatrix(ref m);
58-
UnityEngine.Vector3 sc1 = BSExtensionMethods.ExtractScaleFromMatrix(ref m);
59-
60-
if (p != p1) Debug.Log("Dont match p " + p + " " + p1);
61-
if (q != q1) Debug.Log("Dont match q " + q + " " + q1);
62-
if (sc != sc1) Debug.Log("Dont match p " + sc + " " + sc1);
63-
*/
64-
6537
transform.position = BSExtensionMethods2.ExtractTranslationFromMatrix(ref m);
6638
transform.rotation = BSExtensionMethods2.ExtractRotationFromMatrix(ref m);
6739
transform.localScale = BSExtensionMethods2.ExtractScaleFromMatrix(ref m);

UnityProject/Assets/BulletUnity/Scripts/BPhysicsWorld.cs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
using BulletUnity.Debugging;
88

99

10+
// TODO order of destruction is an issue
11+
// TODO all constraints need to be removed from a rigid body before the rigid body is destroyed / removed
12+
1013
namespace BulletUnity {
1114
public class BPhysicsWorld : MonoBehaviour, IDisposable {
1215

@@ -337,7 +340,7 @@ public bool AddCollisionObject(BCollisionObject co)
337340
{
338341
if (!_isDisposed)
339342
{
340-
BDebug.Log(debugType, "Adding collision object {0} to world", co);
343+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Adding collision object {0} to world", co);
341344
if (co._BuildCollisionObject())
342345
{
343346
m_world.AddCollisionObject(co.GetCollisionObject(), co.m_groupsIBelongTo, co.m_collisionMask);
@@ -361,7 +364,7 @@ public void RemoveCollisionObject(BulletSharp.CollisionObject co)
361364
{
362365
if (!_isDisposed)
363366
{
364-
BDebug.Log(debugType, "Removing collisionObject {0} from world", co.UserObject);
367+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removing collisionObject {0} from world", co.UserObject);
365368
m_world.RemoveCollisionObject(co);
366369
if (co.UserObject is BCollisionObject) ((BCollisionObject)co.UserObject).isInWorld = false;
367370
//TODO handle removing kinematic character controller action
@@ -376,7 +379,7 @@ public bool AddRigidBody(BRigidBody rb)
376379
{
377380
BDebug.LogError(debugType, "World type must not be collision only");
378381
}
379-
BDebug.Log(debugType, "Adding rigidbody {0} to world", rb);
382+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Adding rigidbody {0} to world", rb);
380383
if (rb._BuildCollisionObject())
381384
{
382385
((DiscreteDynamicsWorld)m_world).AddRigidBody((RigidBody)rb.GetCollisionObject(), rb.m_groupsIBelongTo, rb.m_collisionMask);
@@ -395,7 +398,7 @@ public void RemoveRigidBody(BulletSharp.RigidBody rb)
395398
{
396399
BDebug.LogError(debugType, "World type must not be collision only");
397400
}
398-
BDebug.Log(debugType, "Removing rigidbody {0} from world", rb.UserObject);
401+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removing rigidbody {0} from world", rb.UserObject);
399402
((DiscreteDynamicsWorld)m_world).RemoveRigidBody(rb);
400403
if (rb.UserObject is BCollisionObject) ((BCollisionObject)rb.UserObject).isInWorld = false;
401404
}
@@ -408,12 +411,13 @@ public bool AddConstraint(BTypedConstraint c)
408411
if (m_worldType < WorldType.RigidBodyDynamics)
409412
{
410413
BDebug.LogError(debugType, "World type must not be collision only");
414+
return false;
411415
}
412-
BDebug.Log(debugType, "Adding constraint {0} to world", c);
416+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Adding constraint {0} to world", c);
413417
if (c._BuildConstraint())
414418
{
415-
((DiscreteDynamicsWorld)m_world).AddConstraint(c.GetConstraint(), c.disableCollisionsBetweenConstrainedBodies);
416-
c.isInWorld = true;
419+
((DiscreteDynamicsWorld)m_world).AddConstraint(c.GetConstraint(), c.m_disableCollisionsBetweenConstrainedBodies);
420+
c.m_isInWorld = true;
417421
}
418422
return true;
419423
}
@@ -428,22 +432,22 @@ public void RemoveConstraint(BulletSharp.TypedConstraint c)
428432
{
429433
BDebug.LogError(debugType, "World type must not be collision only");
430434
}
431-
BDebug.Log(debugType, "Removing constraint {0} from world", c.Userobject);
435+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removing constraint {0} from world", c.Userobject);
432436
((DiscreteDynamicsWorld)m_world).RemoveConstraint(c);
433-
if (c.Userobject is BTypedConstraint) ((BTypedConstraint)c.Userobject).isInWorld = false;
437+
if (c.Userobject is BTypedConstraint) ((BTypedConstraint)c.Userobject).m_isInWorld = false;
434438
}
435439
}
436440

437441
public bool AddSoftBody(BSoftBody softBody)
438442
{
439443
if (!(m_world is BulletSharp.SoftBody.SoftRigidDynamicsWorld))
440444
{
441-
BDebug.LogError(debugType, "The Physics World must be a BSoftBodyWorld for adding soft bodies");
445+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("The Physics World must be a BSoftBodyWorld for adding soft bodies");
442446
return false;
443447
}
444448
if (!_isDisposed)
445449
{
446-
BDebug.Log(debugType, "Adding softbody {0} to world", softBody);
450+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Adding softbody {0} to world", softBody);
447451
if (softBody._BuildCollisionObject())
448452
{
449453
((BulletSharp.SoftBody.SoftRigidDynamicsWorld)m_world).AddSoftBody((SoftBody)softBody.GetCollisionObject());
@@ -458,7 +462,7 @@ public void RemoveSoftBody(BulletSharp.SoftBody.SoftBody softBody)
458462
{
459463
if (!_isDisposed && m_world is BulletSharp.SoftBody.SoftRigidDynamicsWorld)
460464
{
461-
BDebug.Log(debugType, "Removing softbody {0} from world", softBody.UserObject);
465+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removing softbody {0} from world", softBody.UserObject);
462466
((BulletSharp.SoftBody.SoftRigidDynamicsWorld)m_world).RemoveSoftBody(softBody);
463467
if (softBody.UserObject is BCollisionObject) ((BCollisionObject)softBody.UserObject).isInWorld = false;
464468
}
@@ -550,33 +554,36 @@ protected virtual void _InitializePhysicsWorld() {
550554
}
551555

552556
protected void Dispose(bool disposing) {
553-
BDebug.Log(debugType, "BDynamicsWorld Disposing physics.");
557+
if (debugType <= BDebug.DebugType.Debug) Debug.Log("BDynamicsWorld Disposing physics.");
554558

555-
if (m_world != null) {
559+
if (m_world != null) {
556560
//remove/dispose constraints
557561
int i;
558562
if (_ddWorld != null)
559563
{
564+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removing Constraints {0}", _ddWorld.NumConstraints);
560565
for (i = _ddWorld.NumConstraints - 1; i >= 0; i--)
561566
{
562567
TypedConstraint constraint = _ddWorld.GetConstraint(i);
563568
_ddWorld.RemoveConstraint(constraint);
564-
if (constraint.Userobject is BTypedConstraint) ((BTypedConstraint)constraint.Userobject).isInWorld = false;
565-
if ((debugType & BDebug.DebugType.Debug) == BDebug.DebugType.Debug) Debug.LogFormat("Removed Constaint {0}", constraint.Userobject);
569+
if (constraint.Userobject is BTypedConstraint) ((BTypedConstraint)constraint.Userobject).m_isInWorld = false;
570+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removed Constaint {0}", constraint.Userobject);
566571
constraint.Dispose();
567572
}
568573
}
569574

575+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removing Collision Objects {0}", _ddWorld.NumCollisionObjects);
570576
//remove the rigidbodies from the dynamics world and delete them
571577
for (i = m_world.NumCollisionObjects - 1; i >= 0; i--) {
572578
CollisionObject obj = m_world.CollisionObjectArray[i];
573579
RigidBody body = obj as RigidBody;
574580
if (body != null && body.MotionState != null) {
581+
Debug.Assert(body.NumConstraintRefs == 0, "Rigid body still had constraints");
575582
body.MotionState.Dispose();
576583
}
577584
m_world.RemoveCollisionObject(obj);
578585
if (obj.UserObject is BCollisionObject) ((BCollisionObject)obj.UserObject).isInWorld = false;
579-
if ((debugType & BDebug.DebugType.Debug) == BDebug.DebugType.Debug) Debug.LogFormat("Removed CollisionObject {0}", obj.UserObject);
586+
if (debugType <= BDebug.DebugType.Debug) Debug.LogFormat("Removed CollisionObject {0}", obj.UserObject);
580587
obj.Dispose();
581588
}
582589

UnityProject/Assets/BulletUnity/Scripts/BRigidBody.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,20 +354,46 @@ protected override void Awake() {
354354
}
355355
}
356356

357+
protected override void OnDisable()
358+
{
359+
if (m_rigidBody != null && isInWorld) {
360+
//all constraints using RB must be disabled before rigid body is disabled
361+
for (int i = m_rigidBody.NumConstraintRefs - 1; i >= 0; i--)
362+
{
363+
BTypedConstraint btc = (BTypedConstraint) m_rigidBody.GetConstraintRef(i).Userobject;
364+
Debug.Assert(btc != null);
365+
btc.enabled = false; //should remove it from the scene
366+
}
367+
}
368+
base.OnDisable();
369+
}
370+
357371
protected override void AddObjectToBulletWorld()
358372
{
359373
BPhysicsWorld.Get().AddRigidBody(this);
360374
}
361375

362376
protected override void RemoveObjectFromBulletWorld()
363377
{
364-
BPhysicsWorld.Get().RemoveRigidBody((RigidBody)m_collisionObject);
378+
BPhysicsWorld pw = BPhysicsWorld.Get();
379+
if (pw != null && m_rigidBody != null && isInWorld)
380+
{
381+
Debug.Assert(m_rigidBody.NumConstraintRefs == 0, "Removing rigid body that still had constraints. Remove constraints first.");
382+
//constraints must be removed before rigid body is removed
383+
pw.RemoveRigidBody((RigidBody)m_collisionObject);
384+
}
365385
}
366386

367387
protected override void Dispose(bool isdisposing) {
368388
if (isInWorld && isdisposing && m_rigidBody != null) {
369389
BPhysicsWorld pw = BPhysicsWorld.Get();
370390
if (pw != null && pw.world != null) {
391+
//constraints must be removed before rigid body is removed
392+
for (int i = m_rigidBody.NumConstraintRefs; i > 0; i--)
393+
{
394+
BTypedConstraint tc = (BTypedConstraint) m_rigidBody.GetConstraintRef(i - 1).Userobject;
395+
((DiscreteDynamicsWorld)pw.world).RemoveConstraint(tc.GetConstraint());
396+
}
371397
((DiscreteDynamicsWorld) pw.world).RemoveRigidBody(m_rigidBody);
372398
}
373399
}

UnityProject/Assets/BulletUnity/Scripts/BRigidBody.cs.meta

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)