Package com.bulletphysics.collision.narrowphase

Source Code of com.bulletphysics.collision.narrowphase.GjkConvexCast

/*
* 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.
*/

package com.bulletphysics.collision.narrowphase;

import com.bulletphysics.util.ObjectPool;
import com.bulletphysics.collision.narrowphase.DiscreteCollisionDetectorInterface.ClosestPointInput;
import com.bulletphysics.collision.shapes.ConvexShape;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.linearmath.VectorUtil;
import cz.advel.stack.Stack;
import javax.vecmath.Vector3f;

/**
* GjkConvexCast performs a raycast on a convex object using support mapping.
*
* @author jezek2
*/
public class GjkConvexCast extends ConvexCast {

  //protected final BulletStack stack = BulletStack.get();
  protected final ObjectPool<ClosestPointInput> pointInputsPool = ObjectPool.get(ClosestPointInput.class);

//#ifdef BT_USE_DOUBLE_PRECISION
//  private static final int MAX_ITERATIONS = 64;
//#else
  private static final int MAX_ITERATIONS = 32;
//#endif
 
  private SimplexSolverInterface simplexSolver;
  private ConvexShape convexA;
  private ConvexShape convexB;
 
  private GjkPairDetector gjk = new GjkPairDetector();

  public GjkConvexCast(ConvexShape convexA, ConvexShape convexB, SimplexSolverInterface simplexSolver) {
    this.simplexSolver = simplexSolver;
    this.convexA = convexA;
    this.convexB = convexB;
  }
 
  public boolean calcTimeOfImpact(Transform fromA, Transform toA, Transform fromB, Transform toB, CastResult result) {
    simplexSolver.reset();

    // compute linear velocity for this interval, to interpolate
    // assume no rotation/angular velocity, assert here?
    Vector3f linVelA = Stack.alloc(Vector3f.class);
    Vector3f linVelB = Stack.alloc(Vector3f.class);

    linVelA.sub(toA.origin, fromA.origin);
    linVelB.sub(toB.origin, fromB.origin);

    float radius = 0.001f;
    float lambda = 0f;
    Vector3f v = Stack.alloc(Vector3f.class);
    v.set(1f, 0f, 0f);

    int maxIter = MAX_ITERATIONS;

    Vector3f n = Stack.alloc(Vector3f.class);
    n.set(0f, 0f, 0f);
    boolean hasResult = false;
    Vector3f c = Stack.alloc(Vector3f.class);
    Vector3f r = Stack.alloc(Vector3f.class);
    r.sub(linVelA, linVelB);

    float lastLambda = lambda;
    //btScalar epsilon = btScalar(0.001);

    int numIter = 0;
    // first solution, using GJK

    Transform identityTrans = Stack.alloc(Transform.class);
    identityTrans.setIdentity();

    //result.drawCoordSystem(sphereTr);

    PointCollector pointCollector = new PointCollector();

    gjk.init(convexA, convexB, simplexSolver, null); // penetrationDepthSolver);   
    ClosestPointInput input = pointInputsPool.get();
    input.init();
    try {
      // we don't use margins during CCD
      //  gjk.setIgnoreMargin(true);

      input.transformA.set(fromA);
      input.transformB.set(fromB);
      gjk.getClosestPoints(input, pointCollector, null);

      hasResult = pointCollector.hasResult;
      c.set(pointCollector.pointInWorld);

      if (hasResult) {
        float dist;
        dist = pointCollector.distance;
        n.set(pointCollector.normalOnBInWorld);

        // not close enough
        while (dist > radius) {
          numIter++;
          if (numIter > maxIter) {
            return false; // todo: report a failure
          }
          float dLambda = 0f;

          float projectedLinearVelocity = r.dot(n);

          dLambda = dist / (projectedLinearVelocity);

          lambda = lambda - dLambda;

          if (lambda > 1f) {
            return false;
          }
          if (lambda < 0f) {
            return false;          // todo: next check with relative epsilon
          }
         
          if (lambda <= lastLambda) {
            return false;
          //n.setValue(0,0,0);
          //break;
          }
          lastLambda = lambda;

          // interpolate to next lambda
          result.debugDraw(lambda);
          VectorUtil.setInterpolate3(input.transformA.origin, fromA.origin, toA.origin, lambda);
          VectorUtil.setInterpolate3(input.transformB.origin, fromB.origin, toB.origin, lambda);

          gjk.getClosestPoints(input, pointCollector, null);
          if (pointCollector.hasResult) {
            if (pointCollector.distance < 0f) {
              result.fraction = lastLambda;
              n.set(pointCollector.normalOnBInWorld);
              result.normal.set(n);
              result.hitPoint.set(pointCollector.pointInWorld);
              return true;
            }
            c.set(pointCollector.pointInWorld);
            n.set(pointCollector.normalOnBInWorld);
            dist = pointCollector.distance;
          }
          else {
            // ??
            return false;
          }

        }

        // is n normalized?
        // don't report time of impact for motion away from the contact normal (or causes minor penetration)
        if (n.dot(r) >= -result.allowedPenetration) {
          return false;
        }
        result.fraction = lambda;
        result.normal.set(n);
        result.hitPoint.set(c);
        return true;
      }

      return false;
    }
    finally {
      pointInputsPool.release(input);
    }
  }
 
}
TOP

Related Classes of com.bulletphysics.collision.narrowphase.GjkConvexCast

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.