Package com.bulletphysics.dynamics.constraintsolver

Source Code of com.bulletphysics.dynamics.constraintsolver.RotationalLimitMotor

/*
* Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz>
*
* Bullet Continuous Collision Detection and Physics Library
* Copyright (c) 2003-2008 Erwin Coumans  http://www.bulletphysics.com/
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
*    claim that you wrote the original software. If you use this software
*    in a product, an acknowledgment in the product documentation would be
*    appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

/*
2007-09-09
btGeneric6DofConstraint Refactored by Francisco Le�n
email: projectileman@yahoo.com
http://gimpact.sf.net
*/

package com.bulletphysics.dynamics.constraintsolver;

import com.bulletphysics.BulletGlobals;
import com.bulletphysics.dynamics.RigidBody;
import cz.advel.stack.Stack;
import cz.advel.stack.StaticAlloc;
import javax.vecmath.Vector3f;

/**
* Rotation limit structure for generic joints.
*
* @author jezek2
*/
public class RotationalLimitMotor {
 
  //protected final BulletStack stack = BulletStack.get();

  public float loLimit; //!< joint limit
  public float hiLimit; //!< joint limit
  public float targetVelocity; //!< target motor velocity
  public float maxMotorForce; //!< max force on motor
  public float maxLimitForce; //!< max force on limit
  public float damping; //!< Damping.
  public float limitSoftness; //! Relaxation factor
  public float ERP; //!< Error tolerance factor when joint is at limit
  public float bounce; //!< restitution factor
  public boolean enableMotor;
 
  public float currentLimitError;//!  How much is violated this limit
  public int currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit
  public float accumulatedImpulse;

  public RotationalLimitMotor() {
      accumulatedImpulse = 0.f;
        targetVelocity = 0;
        maxMotorForce = 0.1f;
        maxLimitForce = 300.0f;
        loLimit = -BulletGlobals.SIMD_INFINITY;
        hiLimit = BulletGlobals.SIMD_INFINITY;
        ERP = 0.5f;
        bounce = 0.0f;
        damping = 1.0f;
        limitSoftness = 0.5f;
        currentLimit = 0;
        currentLimitError = 0;
        enableMotor = false;
  }
 
  public RotationalLimitMotor(RotationalLimitMotor limot) {
    targetVelocity = limot.targetVelocity;
    maxMotorForce = limot.maxMotorForce;
    limitSoftness = limot.limitSoftness;
    loLimit = limot.loLimit;
    hiLimit = limot.hiLimit;
    ERP = limot.ERP;
    bounce = limot.bounce;
    currentLimit = limot.currentLimit;
    currentLimitError = limot.currentLimitError;
    enableMotor = limot.enableMotor;
  }

  /**
   * Is limited?
   */
    public boolean isLimited()
    {
      if(loLimit>=hiLimit) return false;
      return true;
    }

  /**
   * Need apply correction?
   */
    public boolean needApplyTorques()
    {
      if(currentLimit == 0 && enableMotor == false) return false;
      return true;
    }

  /**
   * Calculates error. Calculates currentLimit and currentLimitError.
   */
  public int testLimitValue(float test_value) {
    if (loLimit > hiLimit) {
      currentLimit = 0; // Free from violation
      return 0;
    }

    if (test_value < loLimit) {
      currentLimit = 1; // low limit violation
      currentLimitError = test_value - loLimit;
      return 1;
    }
    else if (test_value > hiLimit) {
      currentLimit = 2; // High limit violation
      currentLimitError = test_value - hiLimit;
      return 2;
    }

    currentLimit = 0; // Free from violation
    return 0;
  }

  /**
   * Apply the correction impulses for two bodies.
   */
  @StaticAlloc
  public float solveAngularLimits(float timeStep, Vector3f axis, float jacDiagABInv, RigidBody body0, RigidBody body1) {
    if (needApplyTorques() == false) {
      return 0.0f;
    }

    float target_velocity = this.targetVelocity;
    float maxMotorForce = this.maxMotorForce;

    // current error correction
    if (currentLimit != 0) {
      target_velocity = -ERP * currentLimitError / (timeStep);
      maxMotorForce = maxLimitForce;
    }

    maxMotorForce *= timeStep;

    // current velocity difference
    Vector3f vel_diff = body0.getAngularVelocity(Stack.alloc(Vector3f.class));
    if (body1 != null) {
      vel_diff.sub(body1.getAngularVelocity(Stack.alloc(Vector3f.class)));
    }

    float rel_vel = axis.dot(vel_diff);

    // correction velocity
    float motor_relvel = limitSoftness * (target_velocity - damping * rel_vel);

    if (motor_relvel < BulletGlobals.FLT_EPSILON && motor_relvel > -BulletGlobals.FLT_EPSILON) {
      return 0.0f; // no need for applying force
    }

    // correction impulse
    float unclippedMotorImpulse = (1 + bounce) * motor_relvel * jacDiagABInv;

    // clip correction impulse
    float clippedMotorImpulse;

    // todo: should clip against accumulated impulse
    if (unclippedMotorImpulse > 0.0f) {
      clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce ? maxMotorForce : unclippedMotorImpulse;
    }
    else {
      clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce : unclippedMotorImpulse;
    }

    // sort with accumulated impulses
    float lo = -1e30f;
    float hi = 1e30f;

    float oldaccumImpulse = accumulatedImpulse;
    float sum = oldaccumImpulse + clippedMotorImpulse;
    accumulatedImpulse = sum > hi ? 0f : sum < lo ? 0f : sum;

    clippedMotorImpulse = accumulatedImpulse - oldaccumImpulse;

    Vector3f motorImp = Stack.alloc(Vector3f.class);
    motorImp.scale(clippedMotorImpulse, axis);

    body0.applyTorqueImpulse(motorImp);
    if (body1 != null) {
      motorImp.negate();
      body1.applyTorqueImpulse(motorImp);
    }

    return clippedMotorImpulse;
  }
 
}
TOP

Related Classes of com.bulletphysics.dynamics.constraintsolver.RotationalLimitMotor

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.