File indexing completed on 2024-12-29 03:29:27

0001 /*
0002 * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
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 struct b2PrismaticJointDef : public b2JointDef
0031 {
0032     b2PrismaticJointDef()
0033     {
0034         type = e_prismaticJoint;
0035         localAnchorA.SetZero();
0036         localAnchorB.SetZero();
0037         localAxisA.Set(1.0f, 0.0f);
0038         referenceAngle = 0.0f;
0039         enableLimit = false;
0040         lowerTranslation = 0.0f;
0041         upperTranslation = 0.0f;
0042         enableMotor = false;
0043         maxMotorForce = 0.0f;
0044         motorSpeed = 0.0f;
0045     }
0046 
0047     /// Initialize the bodies, anchors, axis, and reference angle using the world
0048     /// anchor and unit world axis.
0049     void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis);
0050 
0051     /// The local anchor point relative to bodyA's origin.
0052     b2Vec2 localAnchorA;
0053 
0054     /// The local anchor point relative to bodyB's origin.
0055     b2Vec2 localAnchorB;
0056 
0057     /// The local translation unit axis in bodyA.
0058     b2Vec2 localAxisA;
0059 
0060     /// The constrained angle between the bodies: bodyB_angle - bodyA_angle.
0061     float32 referenceAngle;
0062 
0063     /// Enable/disable the joint limit.
0064     bool enableLimit;
0065 
0066     /// The lower translation limit, usually in meters.
0067     float32 lowerTranslation;
0068 
0069     /// The upper translation limit, usually in meters.
0070     float32 upperTranslation;
0071 
0072     /// Enable/disable the joint motor.
0073     bool enableMotor;
0074 
0075     /// The maximum motor torque, usually in N-m.
0076     float32 maxMotorForce;
0077 
0078     /// The desired motor speed in radians per second.
0079     float32 motorSpeed;
0080 };
0081 
0082 /// A prismatic joint. This joint provides one degree of freedom: translation
0083 /// along an axis fixed in bodyA. Relative rotation is prevented. You can
0084 /// use a joint limit to restrict the range of motion and a joint motor to
0085 /// drive the motion or to model joint friction.
0086 class b2PrismaticJoint : public b2Joint
0087 {
0088 public:
0089     b2Vec2 GetAnchorA() const;
0090     b2Vec2 GetAnchorB() const;
0091 
0092     b2Vec2 GetReactionForce(float32 inv_dt) const;
0093     float32 GetReactionTorque(float32 inv_dt) const;
0094 
0095     /// The local anchor point relative to bodyA's origin.
0096     const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; }
0097 
0098     /// The local anchor point relative to bodyB's origin.
0099     const b2Vec2& GetLocalAnchorB() const  { return m_localAnchorB; }
0100 
0101     /// The local joint axis relative to bodyA.
0102     const b2Vec2& GetLocalAxisA() const { return m_localXAxisA; }
0103 
0104     /// Get the reference angle.
0105     float32 GetReferenceAngle() const { return m_referenceAngle; }
0106 
0107     /// Get the current joint translation, usually in meters.
0108     float32 GetJointTranslation() const;
0109 
0110     /// Get the current joint translation speed, usually in meters per second.
0111     float32 GetJointSpeed() const;
0112 
0113     /// Is the joint limit enabled?
0114     bool IsLimitEnabled() const;
0115 
0116     /// Enable/disable the joint limit.
0117     void EnableLimit(bool flag);
0118 
0119     /// Get the lower joint limit, usually in meters.
0120     float32 GetLowerLimit() const;
0121 
0122     /// Get the upper joint limit, usually in meters.
0123     float32 GetUpperLimit() const;
0124 
0125     /// Set the joint limits, usually in meters.
0126     void SetLimits(float32 lower, float32 upper);
0127 
0128     /// Is the joint motor enabled?
0129     bool IsMotorEnabled() const;
0130 
0131     /// Enable/disable the joint motor.
0132     void EnableMotor(bool flag);
0133 
0134     /// Set the motor speed, usually in meters per second.
0135     void SetMotorSpeed(float32 speed);
0136 
0137     /// Get the motor speed, usually in meters per second.
0138     float32 GetMotorSpeed() const;
0139 
0140     /// Set the maximum motor force, usually in N.
0141     void SetMaxMotorForce(float32 force);
0142     float32 GetMaxMotorForce() const { return m_maxMotorForce; }
0143 
0144     /// Get the current motor force given the inverse time step, usually in N.
0145     float32 GetMotorForce(float32 inv_dt) const;
0146 
0147     /// Dump to b2Log
0148     void Dump();
0149 
0150 protected:
0151     friend class b2Joint;
0152     friend class b2GearJoint;
0153     b2PrismaticJoint(const b2PrismaticJointDef* def);
0154 
0155     void InitVelocityConstraints(const b2SolverData& data);
0156     void SolveVelocityConstraints(const b2SolverData& data);
0157     bool SolvePositionConstraints(const b2SolverData& data);
0158 
0159     // Solver shared
0160     b2Vec2 m_localAnchorA;
0161     b2Vec2 m_localAnchorB;
0162     b2Vec2 m_localXAxisA;
0163     b2Vec2 m_localYAxisA;
0164     float32 m_referenceAngle;
0165     b2Vec3 m_impulse;
0166     float32 m_motorImpulse;
0167     float32 m_lowerTranslation;
0168     float32 m_upperTranslation;
0169     float32 m_maxMotorForce;
0170     float32 m_motorSpeed;
0171     bool m_enableLimit;
0172     bool m_enableMotor;
0173     b2LimitState m_limitState;
0174 
0175     // Solver temp
0176     int32 m_indexA;
0177     int32 m_indexB;
0178     b2Vec2 m_localCenterA;
0179     b2Vec2 m_localCenterB;
0180     float32 m_invMassA;
0181     float32 m_invMassB;
0182     float32 m_invIA;
0183     float32 m_invIB;
0184     b2Vec2 m_axis, m_perp;
0185     float32 m_s1, m_s2;
0186     float32 m_a1, m_a2;
0187     b2Mat33 m_K;
0188     float32 m_motorMass;
0189 };
0190 
0191 inline float32 b2PrismaticJoint::GetMotorSpeed() const
0192 {
0193     return m_motorSpeed;
0194 }
0195 
0196 #endif