// Note that this relies on being called at TaintTime void AddAxisLockConstraint() { if (LockAxisConstraint == null) { // Lock that axis by creating a 6DOF constraint that has one end in the world and // the other in the object. // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380 // Remove any existing axis constraint (just to be sure) RemoveAxisLockConstraint(); BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(m_physicsScene.World, m_controllingPrim.PhysBody, OMV.Vector3.Zero, OMV.Quaternion.Identity, false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */); LockAxisConstraint = axisConstrainer; m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); // Remember the clocking being inforce so we can notice if they have changed LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis; LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis; // The constraint is tied to the world and oriented to the prim. if ( !axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh)) { m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits", m_controllingPrim.LocalID); } if ( !axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh)) { m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID); } m_physicsScene.DetailLog( "{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", m_controllingPrim.LocalID, m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh, m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh); // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass); RegisterForBeforeStepCallback(); } }
// Note that this relies on being called at TaintTime void AddAxisLockConstraint() { if (LockAxisConstraint == null) { // Lock that axis by creating a 6DOF constraint that has one end in the world and // the other in the object. // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380 // Remove any existing axis constraint (just to be sure) RemoveAxisLockConstraint (); BSConstraint6Dof axisConstrainer = new BSConstraint6Dof (m_physicsScene.World, m_controllingPrim.PhysBody, OMV.Vector3.Zero, OMV.Quaternion.Identity, false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */); LockAxisConstraint = axisConstrainer; m_physicsScene.Constraints.AddConstraint (LockAxisConstraint); // Remember the clocking being inforce so we can notice if they have changed LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis; LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis; // The constraint is tied to the world and oriented to the prim. if ( !axisConstrainer.SetLinearLimits (m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh)) { m_physicsScene.DetailLog ("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits", m_controllingPrim.LocalID); } if ( !axisConstrainer.SetAngularLimits (m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh)) { m_physicsScene.DetailLog ("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID); } m_physicsScene.DetailLog ( "{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", m_controllingPrim.LocalID, m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh, m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh); // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. axisConstrainer.TranslationalLimitMotor (true /* enable */, 5.0f, 0.1f); axisConstrainer.RecomputeConstraintVariables (m_controllingPrim.RawMass); RegisterForBeforeStepCallback (); } }
// Create a static constraint between the two passed objects BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) { BSLinkInfoConstraint linkInfo = li as BSLinkInfoConstraint; if (linkInfo == null) { return(null); } // Zero motion for children so they don't interpolate li.member.ZeroMotion(true); BSConstraint constrain = null; switch (linkInfo.constraintType) { case ConstraintType.BS_FIXED_CONSTRAINT_TYPE: case ConstraintType.D6_CONSTRAINT_TYPE: // Relative position normalaized to the root prim // Essentually a vector pointing from center of rootPrim to center of li.member OMV.Vector3 childRelativePosition = linkInfo.member.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog( "{0},BSLinksetConstraint.BuildConstraint,6Dof,rBody={1},cBody={2},rLoc={3},cLoc={4},midLoc={5}", rootPrim.LocalID, rootPrim.PhysBody, linkInfo.member.PhysBody, rootPrim.Position, linkInfo.member.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 constrain = new BSConstraint6Dof(PhysicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, midPoint, true, true); /* NOTE: below is an attempt to build constraint with full frame computation, etc. * Using the midpoint is easier since it lets the Bullet code manipulate the transforms * of the objects. * Code left for future programmers. * // ================================================================================== * // relative position normalized to the root prim * OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); * OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation; * * * // relative rotation of the child to the parent * OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; * OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); * * DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); * BS6DofConstraint constrain = new BS6DofConstraint( * PhysicsScene.World, rootPrim.Body, childPrim.Body, * OMV.Vector3.Zero, * OMV.Quaternion.Inverse(rootPrim.Orientation), * OMV.Vector3.Zero, * OMV.Quaternion.Inverse(childPrim.Orientation), * true, * true * ); * // ================================================================================== */ break; case ConstraintType.D6_SPRING_CONSTRAINT_TYPE: constrain = new BSConstraintSpring(PhysicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, linkInfo.frameInAloc, linkInfo.frameInArot, linkInfo.frameInBloc, linkInfo.frameInBrot, linkInfo.useLinearReferenceFrameA, true /*disableCollisionsBetweenLinkedBodies*/); DetailLog("{0},BSLinksetConstraint.BuildConstraint,spring,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, linkInfo.member.LocalID, linkInfo.member.PhysBody.AddrString, rootPrim.Position, linkInfo.member.Position); break; default: break; } if (constrain != null) { linkInfo.SetLinkParameters(constrain); PhysicsScene.Constraints.AddConstraint(constrain); } return(constrain); }
// Create a static constraint between the two passed objects BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) { BSLinkInfoConstraint linkInfo = li as BSLinkInfoConstraint; if (linkInfo == null) return null; // Zero motion for children so they don't interpolate li.member.ZeroMotion(true); BSConstraint constrain = null; switch (linkInfo.constraintType) { case ConstraintType.BS_FIXED_CONSTRAINT_TYPE: case ConstraintType.D6_CONSTRAINT_TYPE: // Relative position normalaized to the root prim // Essentually a vector pointing from center of rootPrim to center of li.member OMV.Vector3 childRelativePosition = linkInfo.member.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition/2); DetailLog( "{0},BSLinksetConstraint.BuildConstraint,6Dof,rBody={1},cBody={2},rLoc={3},cLoc={4},midLoc={5}", rootPrim.LocalID, rootPrim.PhysBody, linkInfo.member.PhysBody, rootPrim.Position, linkInfo.member.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 constrain = new BSConstraint6Dof(PhysicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, midPoint, true, true); /* NOTE: below is an attempt to build constraint with full frame computation, etc. * Using the midpoint is easier since it lets the Bullet code manipulate the transforms * of the objects. * Code left for future programmers. // ================================================================================== // relative position normalized to the root prim OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation; // relative rotation of the child to the parent OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( PhysicsScene.World, rootPrim.Body, childPrim.Body, OMV.Vector3.Zero, OMV.Quaternion.Inverse(rootPrim.Orientation), OMV.Vector3.Zero, OMV.Quaternion.Inverse(childPrim.Orientation), true, true ); // ================================================================================== */ break; case ConstraintType.D6_SPRING_CONSTRAINT_TYPE: constrain = new BSConstraintSpring(PhysicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, linkInfo.frameInAloc, linkInfo.frameInArot, linkInfo.frameInBloc, linkInfo.frameInBrot, linkInfo.useLinearReferenceFrameA, true /*disableCollisionsBetweenLinkedBodies*/); DetailLog("{0},BSLinksetConstraint.BuildConstraint,spring,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, linkInfo.member.LocalID, linkInfo.member.PhysBody.AddrString, rootPrim.Position, linkInfo.member.Position); break; default: break; } linkInfo.SetLinkParameters(constrain); PhysicsScene.Constraints.AddConstraint(constrain); return constrain; }