All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jbox2d.dynamics.joints.Joint Maven / Gradle / Ivy

The newest version!
/*
 * The MIT License (MIT)
 *
 * FXGL - JavaFX Game Library
 *
 * Copyright (c) 2015-2017 AlmasB ([email protected])
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.jbox2d.dynamics.joints;

import com.almasb.fxgl.core.math.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) {
        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:
                throw new IllegalArgumentException("Unknown joint type");
        }
    }

    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() {
        // no default implementation
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy