Creates point constraint (joint) connecting two physics bodies at specified attachment points (returns constraintHandle).
Takes bodyHandle1 (first body physics handle), bodyHandle2 (second body physics handle), point1X/Y/Z (attachment point on body1 in local coordinates), point2X/Y/Z (attachment point on body2 in local coordinates).
Returns constraintHandle (constraint handle for subsequent operations, 0 on failure).
3D Graphics
Parameters & Returns
Parameters
bodyHandle1Int
bodyHandle2Int
point1XDouble
point1YDouble
point1ZDouble
point2XDouble
point2YDouble
point2ZDouble
Returns
Int
Quick Summary
Creates point constraint (joint) connecting two physics bodies at specified attachment points (returns constraintHandle).
Takes bodyHandle1 (first body physics handle), bodyHandle2 (second body physics handle), point1X/Y/Z (attachment point on body1 in local coordinates), point2X/Y/Z (attachment point on body2 in local coordinates).
Returns constraintHandle (constraint handle for subsequent operations, 0 on failure).
Technical Exegesis...
Creates point constraint (joint) connecting two physics bodies at specified attachment points. Takes bodyHandle1 (first body physics handle from b3dCreatePhysicsBody), bodyHandle2 (second body physics handle), point1X/Y/Z (attachment point on body1 in local coordinates relative to body center), point2X/Y/Z (attachment point on body2 in local coordinates relative to body center). Returns constraintHandle (constraint handle for use with b3dDestroyConstraint, 0 on failure).
Creates point constraint (joint) connecting two physics bodies at specified attachment points. Takes bodyHandle1 (first body physics handle from b3dCreatePhysicsBody), bodyHandle2 (second body physics handle), point1X/Y/Z (attachment point on body1 in local coordinates relative to body center), point2X/Y/Z (attachment point on body2 in local coordinates relative to body center). Returns constraintHandle (constraint handle for use with b3dDestroyConstraint, 0 on failure). Creates Jolt PointConstraint connecting bodies like ball-and-socket joint, allows rotation but keeps attachment points together.
Point constraints create ball-and-socket joints where two bodies are connected at a single point. The bodies can rotate freely around this point but cannot separate. Common uses: pendulums (static body connected to swinging body), chains (multiple bodies connected in sequence), ragdolls (limbs connected at joints), rope physics (segments connected end-to-end), wrecking balls (heavy sphere hanging from cable). Attachment points specified in local coordinates: (0, 0, 0) = center of body, (0, 1, 0) = 1 unit above center (top of 2x2x2 cube), (0, -1, 0) = 1 unit below center (bottom of cube), (1, 0, 0) = 1 unit right of center, (-1, 0, 0) = 1 unit left of center. Coordinate system: Y+ is up, X+ is right, Z+ is forward (same as entity coordinates). Local coordinates transform with body rotation (attachment point rotates with body as it spins).
Constraint creation process: (1) validates bodyHandle1/bodyHandle2 exist in g_bodyHandleToBodyID map (returns 0 if not found), (2) gets body positions/rotations from BodyInterface (GetCenterOfMassPosition and GetRotation), (3) transforms local attachment points to world space (worldPoint = bodyPosition + bodyRotation * localPoint), (4) uses body1's world attachment point as constraint anchor (worldPoint1), (5) creates PointConstraintSettings in WorldSpace mode (both mPoint1 and mPoint2 set to same world position), (6) locks both bodies with BodyLockWrite (thread-safe access for constraint creation), (7) creates constraint with settings.Create(body1, body2), (8) releases locks then adds constraint to physics system (AddConstraint), (9) stores in g_constraints map with auto-incremented handle. World space anchor: uses body1's attachment point as pivot because body1 is typically static (immovable anchor point), body2 will swing/move to keep its attachment point at the same world position, this creates proper pendulum behavior where dynamic body hangs from static anchor. If both bodies are dynamic (both have mass>0) they will both move to maintain constraint, pulling toward each other.
Typical usage patterns: Pendulum (static anchor + dynamic weight): body1 = b3dCreatePhysicsBody(anchor, 0, 0.0, 2, 2, 2) then b3dSetPhysicsBodyType(body1, 0) creates static body, body2 = b3dCreatePhysicsBody(weight, 0, 1.0, 2, 2, 2) creates dynamic body, constraint = b3dCreatePointConstraint(body1, body2, 0, -1, 0, 0, 1, 0) connects bottom of body1 to top of body2, body2 swings like pendulum from body1's bottom. Chain link: constraintA = b3dCreatePointConstraint(body1, body2, 0, -1, 0, 0, 1, 0) connects bottom of body1 to top of body2, constraintB = b3dCreatePointConstraint(body2, body3, 0, -1, 0, 0, 1, 0) connects bottom of body2 to top of body3, creates 3-body chain where each hangs from previous. Ragdoll joint: constraint = b3dCreatePointConstraint(torsoBody, armBody, 1, 0.5, 0, 0, 0.5, 0) connects right side of torso to left side of arm at shoulder, allows arm to swing freely around shoulder joint. Side attachment: constraint = b3dCreatePointConstraint(body1, body2, 1, 0, 0, -1, 0, 0) connects right side of body1 to left side of body2, creates horizontal connection.
Physics behavior: constraint maintained by Jolt solver each physics step (60Hz default), applies forces to both bodies to keep attachment points together, allows full 3D rotation around constraint point (6 degrees of freedom minus 3 translation = 3 rotational DOF), violated constraints gradually corrected over multiple frames (soft constraint with error correction), works with gravity/forces/collisions (bodies still affected by all physics). Constraint force: automatically calculated to maintain constraint, can be very large for stiff constraints (bodies snap together quickly), softer if bodies already near constraint position. Body locking: BodyLockWrite required during Create() because constraint needs non-const Body references, locks released before AddConstraint to avoid deadlock (Jolt internally locks when adding), scope-based locking ensures locks always released even on early return.
Handle management: g_nextConstraintHandle auto-increments (starts at 1, unique per constraint), g_constraints map stores Constraint* pointer by handle, handle used for b3dDestroyConstraint to remove constraint later. Constraint lifetime: persists until explicitly destroyed with b3dDestroyConstraint or physics system shutdown, does not automatically destroy when bodies destroyed (must clean up manually), constraint affects bodies every physics step while active. Coordinate transformation math: worldPoint = bodyPosition + bodyRotation * localPoint, bodyRotation is quaternion (Quat::operator* transforms Vec3 by rotation), bodyPosition is RVec3 (double precision world coordinates), result is world position of attachment point accounting for body rotation/translation.
Performance: O(1) constraint creation (instant), constraint solving adds ~5-10% overhead per constraint per frame (Jolt solver iterates all constraints), multiple constraints on same body accumulate (20 constraints = 100-200% overhead), use sparingly for best performance. Common mistakes: swapping point1/point2 coordinates (body1 uses point1, body2 uses point2), forgetting to make body1 static for pendulum (both bodies fall together if both dynamic), using center points (0,0,0 and 0,0,0) instead of actual attachment offsets, not accounting for cube size (default cube is 2x2x2 so edges are at ±1 not ±0.5).
Prerequisites: b3dInitPhysics must be called first (creates g_physicsSystem), both bodies must exist (valid bodyHandle from b3dCreatePhysicsBody), bodies should be positioned correctly before creating constraint (initial positions determine constraint length/configuration). Returns 0 if: g_physicsSystem not initialized, bodyHandle1 invalid, bodyHandle2 invalid, body locking fails, constraint creation fails. Validation: checks g_bodyHandleToBodyID.find() for both handles, checks BodyLockWrite.Succeeded() for both locks, checks Create() returned non-null constraint pointer.
Related functions: b3dDestroyConstraint removes constraint (bodies become independent again), b3dSetPhysicsBodyType sets body type (0=static anchor, 1=kinematic, 2=dynamic), b3dApplyPhysicsImpulse applies force to constrained body (makes pendulum swing), b3dSetPhysicsBodyDamping adds damping to reduce oscillation (angular damping prevents violent spinning at constraint point). Future constraint types (not yet implemented): HingeConstraint (door hinge, limited rotation around axis), SliderConstraint (piston, linear motion along axis), FixedConstraint (weld, no relative motion), ConeConstraint (ragdoll limb, limited cone of rotation).
Advanced usage: Multiple constraints on one body (create complex linkages, ragdolls with many joints), constraint chains (rope/chain with many segments, each connected to next), dynamic structures (destructible bridges where constraints can be removed to break structure), constraint-based mechanisms (doors with hinge constraints, drawbridges with slider constraints). Debugging tips: print body positions to verify constraint working (constrained bodies should move together), check Y coordinates to see pivot point (pendulum should swing around attachment Y position), add angular damping if spinning violently (b3dSetPhysicsBodyDamping with high angular damping), visualize attachment points by creating small sphere entities at world positions.
Example
Example.bam
; Create static anchor box at topLocal anchor:Int = b3dCreateCube(1, 0, 0)
b3dPositionEntity(anchor, 0, 10, 0)
Local anchorBody:Int = b3dCreatePhysicsBody(anchor, -1, 1.0, 0, 0, 0)
b3dSetPhysicsBodyType(anchorBody, 0) ; Make static
; Create dynamic weight box at bottomLocal weight:Int = b3dCreateCube(1, 0, 0)
b3dPositionEntity(weight, 0, 1, 0)
Local weightBody:Int = b3dCreatePhysicsBody(weight, -1, 1.0, 0, 0, 0)
; Connect bottom of anchor (0,-1,0) to top of weight (0,1,0)Local constraint:Int = b3dCreatePointConstraint(anchorBody, weightBody, 0, -1, 0, 0, 1, 0)
; Apply impulse to make it swing
b3dApplyPhysicsImpulse(weightBody, 20, 0, 0)