Package org.jbox2d.dynamics.joints

Source Code of org.jbox2d.dynamics.joints.WeldJoint

/*******************************************************************************
* Copyright (c) 2011, 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.
*     * Neither the name of the <organization> nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* 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 DANIEL MURPHY 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.
******************************************************************************/
/**
* Created at 3:38:38 AM Jan 15, 2011
*/
package org.jbox2d.dynamics.joints;

import org.jbox2d.common.Mat22;
import org.jbox2d.common.Mat33;
import org.jbox2d.common.MathUtils;
import org.jbox2d.common.Settings;
import org.jbox2d.common.Vec2;
import org.jbox2d.common.Vec3;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.TimeStep;
import org.jbox2d.pooling.IWorldPool;

/**
* @author Daniel Murphy
*/
public class WeldJoint extends Joint {
 
  private final Vec2 m_localAnchorA;
  private final Vec2 m_localAnchorB;
  private float m_referenceAngle;

  private final Vec3 m_impulse;

  private final Mat33 m_mass;
 
  /**
   * @param argWorld
   * @param def
   */
  protected WeldJoint(IWorldPool argWorld, WeldJointDef def) {
    super(argWorld, def);
    m_localAnchorA = new Vec2(def.localAnchorA);
    m_localAnchorB = new Vec2(def.localAnchorB);
    m_referenceAngle = def.referenceAngle;

    m_impulse = new Vec3();
    m_impulse.setZero();
   
    m_mass = new Mat33();
  }

  /**
   * @see org.jbox2d.dynamics.joints.Joint#getAnchorA(org.jbox2d.common.Vec2)
   */
  @Override
  public void getAnchorA(Vec2 argOut) {
    m_bodyA.getWorldPointToOut(m_localAnchorA, argOut);
  }
 
  /**
   * @see org.jbox2d.dynamics.joints.Joint#getAnchorB(org.jbox2d.common.Vec2)
   */
  @Override
  public void getAnchorB(Vec2 argOut) {
    m_bodyB.getWorldPointToOut(m_localAnchorB, argOut);
  }
 
  /**
   * @see org.jbox2d.dynamics.joints.Joint#getReactionForce(float, org.jbox2d.common.Vec2)
   */
  @Override
  public void getReactionForce(float inv_dt, Vec2 argOut) {
    argOut.set(m_impulse.x, m_impulse.y);
    argOut.mulLocal(inv_dt);
  }
 
  /**
   * @see org.jbox2d.dynamics.joints.Joint#getReactionTorque(float)
   */
  @Override
  public float getReactionTorque(float inv_dt) {
    return inv_dt * m_impulse.z;
  }
 
  /**
   * @see org.jbox2d.dynamics.joints.Joint#initVelocityConstraints(org.jbox2d.dynamics.TimeStep)
   */
  @Override
  public void initVelocityConstraints(TimeStep step) {
    Body bA = m_bodyA;
    Body bB = m_bodyB;

    // Compute the effective mass matrix.
    final Vec2 rA = pool.popVec2();
    final Vec2 rB = pool.popVec2();
    rA.set(m_localAnchorA).subLocal(bA.getLocalCenter());
    rB.set(m_localAnchorB).subLocal(bB.getLocalCenter());
   
    Mat22.mulToOut(bA.getTransform().R, rA, rA);
    Mat22.mulToOut(bB.getTransform().R, rB, rB);

    // J = [-I -r1_skew I r2_skew]
    //     [ 0       -1 0       1]
    // r_skew = [-ry; rx]

    // Matlab
    // K = [ mA+r1y^2*iA+mB+r2y^2*iB,  -r1y*iA*r1x-r2y*iB*r2x,          -r1y*iA-r2y*iB]
    //     [  -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB,           r1x*iA+r2x*iB]
    //     [          -r1y*iA-r2y*iB,           r1x*iA+r2x*iB,                   iA+iB]

    float mA = bA.m_invMass, mB = bB.m_invMass;
    float iA = bA.m_invI, iB = bB.m_invI;

    m_mass.col1.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;
    m_mass.col2.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;
    m_mass.col3.x = -rA.y * iA - rB.y * iB;
    m_mass.col1.y = m_mass.col2.x;
    m_mass.col2.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;
    m_mass.col3.y = rA.x * iA + rB.x * iB;
    m_mass.col1.z = m_mass.col3.x;
    m_mass.col2.z = m_mass.col3.y;
    m_mass.col3.z = iA + iB;

    if (step.warmStarting)
    {
      // Scale impulses to support a variable time step.
      m_impulse.mulLocal(step.dtRatio);
     
      final Vec2 P = pool.popVec2();
      final Vec2 temp = pool.popVec2();
      P.set(m_impulse.x, m_impulse.y);

      temp.set(P).mulLocal(mA);
      bA.m_linearVelocity.subLocal(temp);
      bA.m_angularVelocity -= iA * (Vec2.cross(rA, P) + m_impulse.z);

      temp.set(P).mulLocal(mB);
      bB.m_linearVelocity.addLocal(temp);
      bB.m_angularVelocity += iB * (Vec2.cross(rB, P) + m_impulse.z);
     
      pool.pushVec2(2);
    }
    else
    {
      m_impulse.setZero();
    }
    pool.pushVec2(2);
  }
 
  /**
   * @see org.jbox2d.dynamics.joints.Joint#solveVelocityConstraints(org.jbox2d.dynamics.TimeStep)
   */
  @Override
  public void solveVelocityConstraints(TimeStep step) {
    Body bA = m_bodyA;
    Body bB = m_bodyB;

    Vec2 vA = bA.m_linearVelocity;
    float wA = bA.m_angularVelocity;
    Vec2 vB = bB.m_linearVelocity;
    float wB = bB.m_angularVelocity;

    float mA = bA.m_invMass, mB = bB.m_invMass;
    float iA = bA.m_invI, iB = bB.m_invI;
   
    final Vec2 rA = pool.popVec2();
    final Vec2 rB = pool.popVec2();
    rA.set(m_localAnchorA).subLocal(bA.getLocalCenter());
    rB.set(m_localAnchorB).subLocal(bB.getLocalCenter());
    Mat22.mulToOut(bA.getTransform().R, rA, rA);
    Mat22.mulToOut(bB.getTransform().R, rB, rB);
   
   
    final Vec2 Cdot1 = pool.popVec2();
    final Vec2 temp = pool.popVec2();
    // Solve point-to-point finalraint
    Vec2.crossToOut(wA, rA, temp);
    Vec2.crossToOut(wB, rB, Cdot1);
    Cdot1.addLocal(vB).subLocal(vA).subLocal(temp);
    float Cdot2 = wB - wA;
   
    final Vec3 Cdot = pool.popVec3();
    Cdot.set(Cdot1.x, Cdot1.y, Cdot2);

    final Vec3 impulse = pool.popVec3();
    m_mass.solve33ToOut(Cdot.negateLocal(), impulse); // just leave Cdot negated..
    m_impulse.addLocal(impulse);

    final Vec2 P = pool.popVec2();
    P.set(impulse.x, impulse.y);

    temp.set(P).mulLocal(mA);
    vA.subLocal(temp);
    wA -= iA * (Vec2.cross(rA, P) + impulse.z);
   
    temp.set(P).mulLocal(mB);
    vB.addLocal(temp);
    wB += iB * (Vec2.cross(rB, P) + impulse.z);

    bA.m_linearVelocity.set(vA);
    bA.m_angularVelocity = wA;
    bB.m_linearVelocity.set(vB);
    bB.m_angularVelocity = wB;
   
    pool.pushVec2(5);
    pool.pushVec3(2);
  }
 
  /**
   * @see org.jbox2d.dynamics.joints.Joint#solvePositionConstraints(float)
   */
  @Override
  public boolean solvePositionConstraints(float baumgarte) {
    Body bA = m_bodyA;
    Body bB = m_bodyB;

    float mA = bA.m_invMass, mB = bB.m_invMass;
    float iA = bA.m_invI, iB = bB.m_invI;

    final Vec2 rA = pool.popVec2();
    final Vec2 rB = pool.popVec2();
    rA.set(m_localAnchorA).subLocal(bA.getLocalCenter());
    rB.set(m_localAnchorB).subLocal(bB.getLocalCenter());
    Mat22.mulToOut(bA.getTransform().R, rA, rA);
    Mat22.mulToOut(bB.getTransform().R, rB, rB);
   
    final Vec2 C1 = pool.popVec2();
    C1.set(bB.m_sweep.c).addLocal(rB).subLocal(bA.m_sweep.c).subLocal(rA);
    float C2 = bB.m_sweep.a - bA.m_sweep.a - m_referenceAngle;

    // Handle large detachment.
    final float k_allowedStretch = 10.0f * Settings.linearSlop;
    float positionError = C1.length();
    float angularError = MathUtils.abs(C2);
    if (positionError > k_allowedStretch){
      iA *= 1.0f;
      iB *= 1.0f;
    }

    m_mass.col1.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB;
    m_mass.col2.x = -rA.y * rA.x * iA - rB.y * rB.x * iB;
    m_mass.col3.x = -rA.y * iA - rB.y * iB;
    m_mass.col1.y = m_mass.col2.x;
    m_mass.col2.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB;
    m_mass.col3.y = rA.x * iA + rB.x * iB;
    m_mass.col1.z = m_mass.col3.x;
    m_mass.col2.z = m_mass.col3.y;
    m_mass.col3.z = iA + iB;

    final Vec3 C = pool.popVec3();
    final Vec3 impulse = pool.popVec3();
    C.set(C1.x, C1.y, C2);

    m_mass.solve33ToOut(C.negateLocal(), impulse); // just leave c negated..

    final Vec2 P = pool.popVec2();
    final Vec2 temp = pool.popVec2();
    P.set(impulse.x, impulse.y);

    temp.set(P).mulLocal(mA);
    bA.m_sweep.c.subLocal(temp);
    bA.m_sweep.a -= iA * (Vec2.cross(rA, P) + impulse.z);

    temp.set(P).mulLocal(mB);
    bB.m_sweep.c.addLocal(temp);
    bB.m_sweep.a += iB * (Vec2.cross(rB, P) + impulse.z);

    bA.synchronizeTransform();
    bB.synchronizeTransform();
   
    pool.pushVec2(5);
    pool.pushVec3(2);

    return positionError <= Settings.linearSlop && angularError <= Settings.angularSlop;
  }
 
}
TOP

Related Classes of org.jbox2d.dynamics.joints.WeldJoint

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.