File indexing completed on 2025-08-03 03:49:59

0001 /*
0002 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
0003 *
0004 * This software is provided 'as-is', without any express or implied
0005 * warranty.  In no event will the authors be held liable for any damages
0006 * arising from the use of this software.
0007 * Permission is granted to anyone to use this software for any purpose,
0008 * including commercial applications, and to alter it and redistribute it
0009 * freely, subject to the following restrictions:
0010 * 1. The origin of this software must not be misrepresented; you must not
0011 * claim that you wrote the original software. If you use this software
0012 * in a product, an acknowledgment in the product documentation would be
0013 * appreciated but is not required.
0014 * 2. Altered source versions must be plainly marked as such, and must not be
0015 * misrepresented as being the original software.
0016 * 3. This notice may not be removed or altered from any source distribution.
0017 */
0018 
0019 #ifndef B2_PRISMATIC_JOINT_H
0020 #define B2_PRISMATIC_JOINT_H
0021 
0022 #include <Box2D/Dynamics/Joints/b2Joint.h>
0023 
0024 /// Prismatic joint definition. This requires defining a line of
0025 /// motion using an axis and an anchor point. The definition uses local
0026 /// anchor points and a local axis so that the initial configuration
0027 /// can violate the constraint slightly. The joint translation is zero
0028 /// when the local anchor points coincide in world space. Using local
0029 /// anchors and a local axis helps when saving and loading a game.
0030 /// @warning at least one body should by dynamic with a non-fixed rotation.
0031 struct b2PrismaticJointDef : public b2JointDef
0032 {
0033     b2PrismaticJointDef()
0034     {
0035         type = e_prismaticJoint;
0036         localAnchorA.SetZero();
0037         localAnchorB.SetZero();
0038         localAxis1.Set(1.0f, 0.0f);
0039         referenceAngle = 0.0f;
0040         enableLimit = false;
0041         lowerTranslation = 0.0f;
0042         upperTranslation = 0.0f;
0043         enableMotor = false;
0044         maxMotorForce = 0.0f;
0045         motorSpeed = 0.0f;
0046     }
0047 
0048     /// Initialize the bodies, anchors, axis, and reference angle using the world
0049     /// anchor and world axis.
0050     void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis);
0051 
0052     /// The local anchor point relative to body1's origin.
0053     b2Vec2 localAnchorA;
0054 
0055     /// The local anchor point relative to body2's origin.
0056     b2Vec2 localAnchorB;
0057 
0058     /// The local translation axis in body1.
0059     b2Vec2 localAxis1;
0060 
0061     /// The constrained angle between the bodies: body2_angle - body1_angle.
0062     qreal referenceAngle;
0063 
0064     /// Enable/disable the joint limit.
0065     bool enableLimit;
0066 
0067     /// The lower translation limit, usually in meters.
0068     qreal lowerTranslation;
0069 
0070     /// The upper translation limit, usually in meters.
0071     qreal upperTranslation;
0072 
0073     /// Enable/disable the joint motor.
0074     bool enableMotor;
0075 
0076     /// The maximum motor torque, usually in N-m.
0077     qreal maxMotorForce;
0078 
0079     /// The desired motor speed in radians per second.
0080     qreal motorSpeed;
0081 };
0082 
0083 /// A prismatic joint. This joint provides one degree of freedom: translation
0084 /// along an axis fixed in body1. Relative rotation is prevented. You can
0085 /// use a joint limit to restrict the range of motion and a joint motor to
0086 /// drive the motion or to model joint friction.
0087 class b2PrismaticJoint : public b2Joint
0088 {
0089 public:
0090     b2Vec2 GetAnchorA() const override;
0091     b2Vec2 GetAnchorB() const override;
0092 
0093     b2Vec2 GetReactionForce(qreal inv_dt) const override;
0094     qreal GetReactionTorque(qreal inv_dt) const override;
0095 
0096     /// Get the current joint translation, usually in meters.
0097     qreal GetJointTranslation() const;
0098 
0099     /// Get the current joint translation speed, usually in meters per second.
0100     qreal GetJointSpeed() const;
0101 
0102     /// Is the joint limit enabled?
0103     bool IsLimitEnabled() const;
0104 
0105     /// Enable/disable the joint limit.
0106     void EnableLimit(bool flag);
0107 
0108     /// Get the lower joint limit, usually in meters.
0109     qreal GetLowerLimit() const;
0110 
0111     /// Get the upper joint limit, usually in meters.
0112     qreal GetUpperLimit() const;
0113 
0114     /// Set the joint limits, usually in meters.
0115     void SetLimits(qreal lower, qreal upper);
0116 
0117     /// Is the joint motor enabled?
0118     bool IsMotorEnabled() const;
0119 
0120     /// Enable/disable the joint motor.
0121     void EnableMotor(bool flag);
0122 
0123     /// Set the motor speed, usually in meters per second.
0124     void SetMotorSpeed(qreal speed);
0125 
0126     /// Get the motor speed, usually in meters per second.
0127     qreal GetMotorSpeed() const;
0128 
0129     /// Set the maximum motor force, usually in N.
0130     void SetMaxMotorForce(qreal force);
0131 
0132     /// Get the current motor force given the inverse time step, usually in N.
0133     qreal GetMotorForce(qreal inv_dt) const;
0134 
0135 protected:
0136     friend class b2Joint;
0137     friend class b2GearJoint;
0138     b2PrismaticJoint(const b2PrismaticJointDef* def);
0139 
0140     void InitVelocityConstraints(const b2TimeStep& step) override;
0141     void SolveVelocityConstraints(const b2TimeStep& step) override;
0142     bool SolvePositionConstraints(qreal baumgarte) override;
0143 
0144     b2Vec2 m_localAnchor1;
0145     b2Vec2 m_localAnchor2;
0146     b2Vec2 m_localXAxis1;
0147     b2Vec2 m_localYAxis1;
0148     qreal m_refAngle;
0149 
0150     b2Vec2 m_axis, m_perp;
0151     qreal m_s1, m_s2;
0152     qreal m_a1, m_a2;
0153 
0154     b2Mat33 m_K;
0155     b2Vec3 m_impulse;
0156 
0157     qreal m_motorMass;          // effective mass for motor/limit translational constraint.
0158     qreal m_motorImpulse;
0159 
0160     qreal m_lowerTranslation;
0161     qreal m_upperTranslation;
0162     qreal m_maxMotorForce;
0163     qreal m_motorSpeed;
0164     
0165     bool m_enableLimit;
0166     bool m_enableMotor;
0167     b2LimitState m_limitState;
0168 };
0169 
0170 inline qreal b2PrismaticJoint::GetMotorSpeed() const
0171 {
0172     return m_motorSpeed;
0173 }
0174 
0175 #endif