void RemoveAxisLockConstraint() { UnRegisterForBeforeStepCallback(); if (LockAxisConstraint != null) { m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); LockAxisConstraint = null; m_physicsScene.DetailLog("{0},BSActorLockAxis.RemoveAxisLockConstraint,destroyingConstraint", m_controllingPrim.LocalID); } }
public bool AddConstraint(BSConstraint cons) { lock (m_constraints) { // There is only one constraint between any bodies. Remove any old just to make sure. RemoveAndDestroyConstraint(cons.Body1, cons.Body2); m_constraints.Add(cons); } return(true); }
// The constraint MUST exist in the collection // Could be called if the constraint was previously removed. // Return 'true' if the constraint was actually removed and disposed. public bool RemoveAndDestroyConstraint(BSConstraint constrain) { bool removed = false; lock (m_constraints) { // remove the constraint from our collection removed = m_constraints.Remove(constrain); } // Dispose() is safe to call multiple times constrain.Dispose(); return(removed); }
// 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(); } }
// Get the constraint between two bodies. There can be only one. // Return 'true' if a constraint was found. public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint) { bool found = false; BSConstraint foundConstraint = null; uint lookingID1 = body1.ID; uint lookingID2 = body2.ID; lock (m_constraints) { foreach (BSConstraint constrain in m_constraints) { if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) { foundConstraint = constrain; found = true; break; } } } returnConstraint = foundConstraint; return(found); }
public BSLinkInfoConstraint(BSPrimLinkable pMember) : base(pMember) { constraint = null; ResetLink(); member.PhysicsScene.DetailLog("{0},BSLinkInfoConstraint.creation", member.LocalID); }
// 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); }
public virtual void SetLinkParameters(BSConstraint constrain) { }
public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) { m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); LockAxisConstraint = null; }