// Given a constraint, apply the current constraint parameters to same. public void SetConstraintParameters(BSConstraint constrain) { switch (constraintType) { case ConstraintType.D6_CONSTRAINT_TYPE: BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; if (constrain6dof != null) { // zero linear and angular limits makes the objects unable to move in relation to each other constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); // tweek the constraint to increase stability constrain6dof.UseFrameOffset(useFrameOffset); constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); constrain6dof.SetCFMAndERP(cfm, erp); if (solverIterations != 0f) { constrain6dof.SetSolverIterations(solverIterations); } } break; default: break; } }
private 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); // The constraint is tied to the world and oriented to the prim. // Free to move linearly in the region OMV.Vector3 linearLow = OMV.Vector3.Zero; OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.WorldMax; axisConstrainer.SetLinearLimits(linearLow, linearHigh); // Angular with some axis locked float fPI = (float)Math.PI; OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI); OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI); if (m_controllingPrim.LockedAxis.X != 1f) { angularLow.X = 0f; angularHigh.X = 0f; } if (m_controllingPrim.LockedAxis.Y != 1f) { angularLow.Y = 0f; angularHigh.Y = 0f; } if (m_controllingPrim.LockedAxis.Z != 1f) { angularLow.Z = 0f; angularHigh.Z = 0f; } if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh)) { 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, linearLow, linearHigh, angularLow, angularHigh); // 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); } }
private 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 inforced 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); } }
private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(true); // Relative position normalized to the root prim // Essentually a vector pointing from center of rootPrim to center of childPrim OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, childPrim.LocalID, childPrim.PhysBody.AddrString, rootPrim.Position, childPrim.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 BSConstraint6Dof constrain = new BSConstraint6Dof( PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true); // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, 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 = (childPrim.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 * ); * // ================================================================================== */ PhysicsScene.Constraints.AddConstraint(constrain); // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); // tweek the constraint to increase stability constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, BSParam.LinkConstraintTransMotorMaxVel, BSParam.LinkConstraintTransMotorMaxForce); constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); if (BSParam.LinkConstraintSolverIterations != 0f) { constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); } return(constrain); }
private 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); // The constraint is tied to the world and oriented to the prim. // Free to move linearly in the region // OMV.Vector3 linearLow = OMV.Vector3.Zero; // OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize; OMV.Vector3 linearLow = new OMV.Vector3(-10000f, -10000f, -10000f); OMV.Vector3 linearHigh = new OMV.Vector3(10000f, 10000f, 10000f); if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis) { linearLow.X = m_controllingPrim.RawPosition.X; linearHigh.X = m_controllingPrim.RawPosition.X; } if (m_controllingPrim.LockedLinearAxis.Y != BSPhysObject.FreeAxis) { linearLow.Y = m_controllingPrim.RawPosition.Y; linearHigh.Y = m_controllingPrim.RawPosition.Y; } if (m_controllingPrim.LockedLinearAxis.Z != BSPhysObject.FreeAxis) { linearLow.Z = m_controllingPrim.RawPosition.Z; linearHigh.Z = m_controllingPrim.RawPosition.Z; } axisConstrainer.SetLinearLimits(linearLow, linearHigh); // Angular with some axis locked float fPI = (float)Math.PI; OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI); OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI); if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis) { angularLow.X = 0f; angularHigh.X = 0f; } if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis) { angularLow.Y = 0f; angularHigh.Y = 0f; } if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis) { angularLow.Z = 0f; angularHigh.Z = 0f; } if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh)) { 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, linearLow, linearHigh, angularLow, angularHigh); // 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); } }
private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(true); // Relative position normalized to the root prim // Essentually a vector pointing from center of rootPrim to center of childPrim OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, childPrim.LocalID, childPrim.PhysBody.AddrString, rootPrim.Position, childPrim.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 BSConstraint6Dof constrain = new BSConstraint6Dof( PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, 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 = (childPrim.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 ); // ================================================================================== */ PhysicsScene.Constraints.AddConstraint(constrain); // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); // tweek the constraint to increase stability constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, BSParam.LinkConstraintTransMotorMaxVel, BSParam.LinkConstraintTransMotorMaxForce); constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); if (BSParam.LinkConstraintSolverIterations != 0f) { constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); } return constrain; }
// Create a static constraint between the two passed objects private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) { BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint; if (liConstraint == null) { return(null); } // Zero motion for children so they don't interpolate li.member.ZeroMotion(true); BSConstraint constrain = null; switch (liConstraint.constraintType) { case ConstraintType.D6_CONSTRAINT_TYPE: // Relative position normalized to the root prim // Essentually a vector pointing from center of rootPrim to center of li.member OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString, rootPrim.Position, liConstraint.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( m_physicsScene.World, rootPrim.PhysBody, liConstraint.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 * liConstraint.member.Orientation; * OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); * * DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID); * constrain = new BS6DofConstraint( * PhysicsScene.World, rootPrim.Body, liConstraint.member.Body, * OMV.Vector3.Zero, * OMV.Quaternion.Inverse(rootPrim.Orientation), * OMV.Vector3.Zero, * OMV.Quaternion.Inverse(liConstraint.member.Orientation), * true, * true * ); * // ================================================================================== */ break; default: break; } liConstraint.SetConstraintParameters(constrain); m_physicsScene.Constraints.AddConstraint(constrain); return(constrain); }
// Given a constraint, apply the current constraint parameters to same. public override void SetLinkParameters(BSConstraint constrain) { member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType); switch (constraintType) { case ConstraintType.FIXED_CONSTRAINT_TYPE: case ConstraintType.D6_CONSTRAINT_TYPE: BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; if (constrain6dof != null) { // NOTE: D6_SPRING_CONSTRAINT_TYPE should be updated if you change any of this code. // zero linear and angular limits makes the objects unable to move in relation to each other constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); // tweek the constraint to increase stability constrain6dof.UseFrameOffset(useFrameOffset); constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); constrain6dof.SetCFMAndERP(cfm, erp); if (solverIterations != 0f) { constrain6dof.SetSolverIterations(solverIterations); } } break; case ConstraintType.D6_SPRING_CONSTRAINT_TYPE: BSConstraintSpring constrainSpring = constrain as BSConstraintSpring; if (constrainSpring != null) { // zero linear and angular limits makes the objects unable to move in relation to each other constrainSpring.SetLinearLimits(linearLimitLow, linearLimitHigh); constrainSpring.SetAngularLimits(angularLimitLow, angularLimitHigh); // tweek the constraint to increase stability constrainSpring.UseFrameOffset(useFrameOffset); constrainSpring.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); constrainSpring.SetCFMAndERP(cfm, erp); if (solverIterations != 0f) { constrainSpring.SetSolverIterations(solverIterations); } for (int ii = 0; ii < springAxisEnable.Length; ii++) { constrainSpring.SetAxisEnable(ii, springAxisEnable[ii]); if (springDamping[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED) { constrainSpring.SetDamping(ii, springDamping[ii]); } if (springStiffness[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED) { constrainSpring.SetStiffness(ii, springStiffness[ii]); } } constrainSpring.CalculateTransforms(); if (springLinearEquilibriumPoint != OMV.Vector3.Zero) { constrainSpring.SetEquilibriumPoint(springLinearEquilibriumPoint, springAngularEquilibriumPoint); } else { constrainSpring.SetEquilibriumPoint(BSAPITemplate.SPRING_NOT_SPECIFIED, BSAPITemplate.SPRING_NOT_SPECIFIED); } } break; default: break; } }
// Create a static constraint between the two passed objects private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) { BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint; if (liConstraint == null) return null; // Zero motion for children so they don't interpolate li.member.ZeroMotion(true); BSConstraint constrain = null; switch (liConstraint.constraintType) { case ConstraintType.D6_CONSTRAINT_TYPE: // Relative position normalized to the root prim // Essentually a vector pointing from center of rootPrim to center of li.member OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString, rootPrim.Position, liConstraint.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( m_physicsScene.World, rootPrim.PhysBody, liConstraint.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 * liConstraint.member.Orientation; OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID); constrain = new BS6DofConstraint( PhysicsScene.World, rootPrim.Body, liConstraint.member.Body, OMV.Vector3.Zero, OMV.Quaternion.Inverse(rootPrim.Orientation), OMV.Vector3.Zero, OMV.Quaternion.Inverse(liConstraint.member.Orientation), true, true ); // ================================================================================== */ break; default: break; } liConstraint.SetConstraintParameters(constrain); m_physicsScene.Constraints.AddConstraint(constrain); return constrain; }
// Note that this relies on being called at TaintTime private 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 inforced 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(); } }
public override void LockAngularMotion(OMV.Vector3 axis) { DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); // "1" means free, "0" means locked OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); if (axis.X != 1) locking.X = 0f; if (axis.Y != 1) locking.Y = 0f; if (axis.Z != 1) locking.Z = 0f; LockedAxis = locking; if (TryExperimentalLockAxisCode && LockedAxis != LockedAxisFree) { // 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 PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate() { CleanUpLockAxisPhysicals(true /* inTaintTime */); BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, PhysBody, OMV.Vector3.Zero, OMV.Quaternion.Inverse(RawOrientation), true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */); LockAxisConstraint = axisConstrainer; PhysicsScene.Constraints.AddConstraint(LockAxisConstraint); // The constraint is tied to the world and oriented to the prim. // Free to move linearly OMV.Vector3 linearLow = OMV.Vector3.Zero; OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize; axisConstrainer.SetLinearLimits(linearLow, linearHigh); // Angular with some axis locked float f2PI = (float)Math.PI * 2f; OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI); OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI); if (LockedAxis.X != 1f) { angularLow.X = 0f; angularHigh.X = 0f; } if (LockedAxis.Y != 1f) { angularLow.Y = 0f; angularHigh.Y = 0f; } if (LockedAxis.Z != 1f) { angularLow.Z = 0f; angularHigh.Z = 0f; } axisConstrainer.SetAngularLimits(angularLow, angularHigh); DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}", LocalID, linearLow, linearHigh, angularLow, angularHigh); // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); axisConstrainer.RecomputeConstraintVariables(RawMass); }); } else { // Everything seems unlocked CleanUpLockAxisPhysicals(false /* inTaintTime */); } return; }