org.jbox2d.dynamics.joints.Joint Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2013, Daniel Murphy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
package org.jbox2d.dynamics.joints;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.SolverData;
import org.jbox2d.dynamics.World;
import org.jbox2d.pooling.IWorldPool;
// updated to rev 100
/**
* The base joint class. Joints are used to constrain two bodies together in various fashions. Some
* joints also feature limits and motors.
*
* @author Daniel Murphy
*/
public abstract class Joint {
public static Joint create(World world, JointDef def) {
// Joint joint = null;
switch (def.type) {
case MOUSE:
return new MouseJoint(world.getPool(), (MouseJointDef) def);
case DISTANCE:
return new DistanceJoint(world.getPool(), (DistanceJointDef) def);
case PRISMATIC:
return new PrismaticJoint(world.getPool(), (PrismaticJointDef) def);
case REVOLUTE:
return new RevoluteJoint(world.getPool(), (RevoluteJointDef) def);
case WELD:
return new WeldJoint(world.getPool(), (WeldJointDef) def);
case FRICTION:
return new FrictionJoint(world.getPool(), (FrictionJointDef) def);
case WHEEL:
return new WheelJoint(world.getPool(), (WheelJointDef) def);
case GEAR:
return new GearJoint(world.getPool(), (GearJointDef) def);
case PULLEY:
return new PulleyJoint(world.getPool(), (PulleyJointDef) def);
case CONSTANT_VOLUME:
return new ConstantVolumeJoint(world, (ConstantVolumeJointDef) def);
case ROPE:
return new RopeJoint(world.getPool(), (RopeJointDef) def);
case MOTOR:
return new MotorJoint(world.getPool(), (MotorJointDef) def);
case UNKNOWN:
default:
return null;
}
}
public static void destroy(Joint joint) {
joint.destructor();
}
private final JointType m_type;
public Joint m_prev;
public Joint m_next;
public JointEdge m_edgeA;
public JointEdge m_edgeB;
protected Body m_bodyA;
protected Body m_bodyB;
public boolean m_islandFlag;
private boolean m_collideConnected;
public Object m_userData;
protected IWorldPool pool;
// Cache here per time step to reduce cache misses.
// final Vec2 m_localCenterA, m_localCenterB;
// float m_invMassA, m_invIA;
// float m_invMassB, m_invIB;
protected Joint(IWorldPool worldPool, JointDef def) {
assert (def.bodyA != def.bodyB);
pool = worldPool;
m_type = def.type;
m_prev = null;
m_next = null;
m_bodyA = def.bodyA;
m_bodyB = def.bodyB;
m_collideConnected = def.collideConnected;
m_islandFlag = false;
m_userData = def.userData;
m_edgeA = new JointEdge();
m_edgeA.joint = null;
m_edgeA.other = null;
m_edgeA.prev = null;
m_edgeA.next = null;
m_edgeB = new JointEdge();
m_edgeB.joint = null;
m_edgeB.other = null;
m_edgeB.prev = null;
m_edgeB.next = null;
// m_localCenterA = new Vec2();
// m_localCenterB = new Vec2();
}
/**
* get the type of the concrete joint.
*
* @return
*/
public JointType getType() {
return m_type;
}
/**
* get the first body attached to this joint.
*/
public final Body getBodyA() {
return m_bodyA;
}
/**
* get the second body attached to this joint.
*
* @return
*/
public final Body getBodyB() {
return m_bodyB;
}
/**
* get the anchor point on bodyA in world coordinates.
*
* @return
*/
public abstract void getAnchorA(Vec2 out);
/**
* get the anchor point on bodyB in world coordinates.
*
* @return
*/
public abstract void getAnchorB(Vec2 out);
/**
* get the reaction force on body2 at the joint anchor in Newtons.
*
* @param inv_dt
* @return
*/
public abstract void getReactionForce(float inv_dt, Vec2 out);
/**
* get the reaction torque on body2 in N*m.
*
* @param inv_dt
* @return
*/
public abstract float getReactionTorque(float inv_dt);
/**
* get the next joint the world joint list.
*/
public Joint getNext() {
return m_next;
}
/**
* get the user data pointer.
*/
public Object getUserData() {
return m_userData;
}
/**
* Set the user data pointer.
*/
public void setUserData(Object data) {
m_userData = data;
}
/**
* Get collide connected. Note: modifying the collide connect flag won't work correctly because
* the flag is only checked when fixture AABBs begin to overlap.
*/
public final boolean getCollideConnected() {
return m_collideConnected;
}
/**
* Short-cut function to determine if either body is inactive.
*
* @return
*/
public boolean isActive() {
return m_bodyA.isActive() && m_bodyB.isActive();
}
/** Internal */
public abstract void initVelocityConstraints(SolverData data);
/** Internal */
public abstract void solveVelocityConstraints(SolverData data);
/**
* This returns true if the position errors are within tolerance. Internal.
*/
public abstract boolean solvePositionConstraints(SolverData data);
/**
* Override to handle destruction of joint
*/
public void destructor() {}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy