stride3d/stride · error · Exception

A Gear constraint always needs two rigidbodies to be…

Error message

A Gear constraint always needs two rigidbodies to be created.

What it means

When creating a constraint via Simulation's constraint creation API, a Gear constraint requires two rigid bodies to be constructed because the underlying BulletSharp.GearConstraint needs both rbA and rbB. If rigidBodyB is null the library throws this Exception rather than building a one-sided constraint. Gear constraints couple the rotation of two bodies, so a second body is mandatory.

Solutions

  1. Ensure rigidBodyB is a valid, registered RigidbodyComponent before requesting a Gear constraint
  2. Verify the lookup of the second body (by entity/component reference) actually succeeded and is not null
  3. Use a different constraint type if a single-body constraint was intended

Example fix

// before
var c = simulation.CreateConstraint(ConstraintTypes.Gear, bodyA, null, frameA, frameB);
// after
if (bodyB == null) throw new InvalidOperationException("Gear constraint requires bodyB");
var c = simulation.CreateConstraint(ConstraintTypes.Gear, bodyA, bodyB, frameA, frameB);
Defensive patterns

Strategy: validation

Validate before calling

if (rigidBodyB == null) throw new InvalidOperationException("Gear constraint requires two rigidbodies");

Try / catch

try { sim.CreateConstraint(ConstraintTypes.Gear, bodyA, bodyB, fa, fb); } catch (Exception e) { Log.Error(e.Message); }

Prevention

When it happens

Trigger: Calling the constraint creation switch path with ConstraintTypes.Gear while passing null for rigidBodyB (only rigidBodyA supplied).

Common situations: Developers create gear constraints programmatically and forget to fetch/assign the second body (e.g. body not yet spawned, or lookup by name returned null), unlike simpler joint types where a single-body frame is sometimes acceptable.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/cbe858a429ab3eb1. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Physics/Simulation.cs:793

                    var constraint = new Generic6DoFSpringConstraint
                    {
                        InternalGeneric6DofSpringConstraint =  
                            rigidBodyB == null ? 
                                new BulletSharp.Generic6DofSpringConstraint(rbA, frameA, useReferenceFrameA) :
                                new BulletSharp.Generic6DofSpringConstraint(rbA, rbB, frameA, frameB, useReferenceFrameA),
                    };
                    constraintBase = constraint;

                    constraint.InternalConstraint = constraint.InternalGeneric6DofConstraint = constraint.InternalGeneric6DofSpringConstraint;
                    break;
                }
                case ConstraintTypes.Gear:
                {
                    var constraint = new GearConstraint
                    {
                        InternalGearConstraint =  
                            rigidBodyB == null ? 
                                throw new Exception("A Gear constraint always needs two rigidbodies to be created.") :
                                new BulletSharp.GearConstraint(rbA, rbB, frameA.TranslationVector, frameB.TranslationVector),
                    };
                    constraintBase = constraint;

                    constraint.InternalConstraint = constraint.InternalGearConstraint;
                    break;
                }
                default:
                    throw new ArgumentException(type.ToString());
            }

            if(rigidBodyB != null)
            {
                constraintBase.RigidBodyB = rigidBodyB;
                rigidBodyB.LinkedConstraints.Add(constraintBase);
            }
            constraintBase.RigidBodyA = rigidBodyA;
            rigidBodyA.LinkedConstraints.Add(constraintBase);

View on GitHub (pinned to 96fad776d2)