// 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();
            }
        }
            // 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.BS_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;
                }
            }
Beispiel #3
0
    // 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();
        }
    }