Package com.bulletphysics.collision.dispatch

Source Code of com.bulletphysics.collision.dispatch.ConvexConvexAlgorithm$CreateFunc

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

import com.bulletphysics.util.ObjectPool;
import com.bulletphysics.collision.broadphase.CollisionAlgorithm;
import com.bulletphysics.collision.broadphase.CollisionAlgorithmConstructionInfo;
import com.bulletphysics.collision.broadphase.DispatcherInfo;
import com.bulletphysics.collision.narrowphase.ConvexCast;
import com.bulletphysics.collision.narrowphase.ConvexPenetrationDepthSolver;
import com.bulletphysics.collision.narrowphase.DiscreteCollisionDetectorInterface.ClosestPointInput;
import com.bulletphysics.collision.narrowphase.GjkConvexCast;
import com.bulletphysics.collision.narrowphase.GjkPairDetector;
import com.bulletphysics.collision.narrowphase.PersistentManifold;
import com.bulletphysics.collision.narrowphase.SimplexSolverInterface;
import com.bulletphysics.collision.narrowphase.VoronoiSimplexSolver;
import com.bulletphysics.collision.shapes.ConvexShape;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.util.ObjectArrayList;
import cz.advel.stack.Stack;
import javax.vecmath.Vector3f;

/**
* ConvexConvexAlgorithm collision algorithm implements time of impact, convex
* closest points and penetration depth calculations.
*
* @author jezek2
*/
public class ConvexConvexAlgorithm extends CollisionAlgorithm {
 
  protected final ObjectPool<ClosestPointInput> pointInputsPool = ObjectPool.get(ClosestPointInput.class);

  private GjkPairDetector gjkPairDetector = new GjkPairDetector();

  public boolean ownManifold;
  public PersistentManifold manifoldPtr;
  public boolean lowLevelOfDetail;
 
  public void init(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1, SimplexSolverInterface simplexSolver, ConvexPenetrationDepthSolver pdSolver) {
    super.init(ci);
    gjkPairDetector.init(null, null, simplexSolver, pdSolver);
    this.manifoldPtr = mf;
    this.ownManifold = false;
    this.lowLevelOfDetail = false;
  }
 
  @Override
  public void destroy() {
    if (ownManifold) {
      if (manifoldPtr != null) {
        dispatcher.releaseManifold(manifoldPtr);
      }
      manifoldPtr = null;
    }
  }

  public void setLowLevelOfDetail(boolean useLowLevel) {
    this.lowLevelOfDetail = useLowLevel;
  }

  /**
   * Convex-Convex collision algorithm.
   */
  @Override
  public void processCollision(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut) {
    if (manifoldPtr == null) {
      // swapped?
      manifoldPtr = dispatcher.getNewManifold(body0, body1);
      ownManifold = true;
    }
    resultOut.setPersistentManifold(manifoldPtr);

//  #ifdef USE_BT_GJKEPA
//    btConvexShape*        shape0(static_cast<btConvexShape*>(body0->getCollisionShape()));
//    btConvexShape*        shape1(static_cast<btConvexShape*>(body1->getCollisionShape()));
//    const btScalar        radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/);
//    btGjkEpaSolver::sResults  results;
//    if(btGjkEpaSolver::Collide(  shape0,body0->getWorldTransform(),
//                  shape1,body1->getWorldTransform(),
//                  radialmargin,results))
//      {
//      dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
//      resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
//      }
//  #else

    ConvexShape min0 = (ConvexShape) body0.getCollisionShape();
    ConvexShape min1 = (ConvexShape) body1.getCollisionShape();

    ClosestPointInput input = pointInputsPool.get();
    input.init();

    // JAVA NOTE: original: TODO: if (dispatchInfo.m_useContinuous)
    gjkPairDetector.setMinkowskiA(min0);
    gjkPairDetector.setMinkowskiB(min1);
    input.maximumDistanceSquared = min0.getMargin() + min1.getMargin() + manifoldPtr.getContactBreakingThreshold();
    input.maximumDistanceSquared *= input.maximumDistanceSquared;
    //input.m_stackAlloc = dispatchInfo.m_stackAllocator;

    //  input.m_maximumDistanceSquared = btScalar(1e30);

    body0.getWorldTransform(input.transformA);
    body1.getWorldTransform(input.transformB);

    gjkPairDetector.getClosestPoints(input, resultOut, dispatchInfo.debugDraw);
   
    pointInputsPool.release(input);
    //  #endif

    if (ownManifold) {
      resultOut.refreshContactPoints();
    }
  }

  private static boolean disableCcd = false;
 
  @Override
  public float calculateTimeOfImpact(CollisionObject col0, CollisionObject col1, DispatcherInfo dispatchInfo, ManifoldResult resultOut) {
    Vector3f tmp = Stack.alloc(Vector3f.class);
   
    Transform tmpTrans1 = Stack.alloc(Transform.class);
    Transform tmpTrans2 = Stack.alloc(Transform.class);

    // Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold

    // Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
    // col0->m_worldTransform,
    float resultFraction = 1f;

    tmp.sub(col0.getInterpolationWorldTransform(tmpTrans1).origin, col0.getWorldTransform(tmpTrans2).origin);
    float squareMot0 = tmp.lengthSquared();

    tmp.sub(col1.getInterpolationWorldTransform(tmpTrans1).origin, col1.getWorldTransform(tmpTrans2).origin);
    float squareMot1 = tmp.lengthSquared();

    if (squareMot0 < col0.getCcdSquareMotionThreshold() &&
        squareMot1 < col1.getCcdSquareMotionThreshold()) {
      return resultFraction;
    }

    if (disableCcd) {
      return 1f;
    }
   
    Transform tmpTrans3 = Stack.alloc(Transform.class);
    Transform tmpTrans4 = Stack.alloc(Transform.class);

    // An adhoc way of testing the Continuous Collision Detection algorithms
    // One object is approximated as a sphere, to simplify things
    // Starting in penetration should report no time of impact
    // For proper CCD, better accuracy and handling of 'allowed' penetration should be added
    // also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)

    // Convex0 against sphere for Convex1
    {
      ConvexShape convex0 = (ConvexShape) col0.getCollisionShape();

      SphereShape sphere1 = new SphereShape(col1.getCcdSweptSphereRadius()); // todo: allow non-zero sphere sizes, for better approximation
      ConvexCast.CastResult result = new ConvexCast.CastResult();
      VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
      //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
      ///Simplification, one object is simplified as a sphere
      GjkConvexCast ccd1 = new GjkConvexCast(convex0, sphere1, voronoiSimplex);
      //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
      if (ccd1.calcTimeOfImpact(col0.getWorldTransform(tmpTrans1), col0.getInterpolationWorldTransform(tmpTrans2),
          col1.getWorldTransform(tmpTrans3), col1.getInterpolationWorldTransform(tmpTrans4), result)) {
        // store result.m_fraction in both bodies

        if (col0.getHitFraction() > result.fraction) {
          col0.setHitFraction(result.fraction);
        }

        if (col1.getHitFraction() > result.fraction) {
          col1.setHitFraction(result.fraction);
        }

        if (resultFraction > result.fraction) {
          resultFraction = result.fraction;
        }
      }
    }

    // Sphere (for convex0) against Convex1
    {
      ConvexShape convex1 = (ConvexShape) col1.getCollisionShape();

      SphereShape sphere0 = new SphereShape(col0.getCcdSweptSphereRadius()); // todo: allow non-zero sphere sizes, for better approximation
      ConvexCast.CastResult result = new ConvexCast.CastResult();
      VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
      //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
      ///Simplification, one object is simplified as a sphere
      GjkConvexCast ccd1 = new GjkConvexCast(sphere0, convex1, voronoiSimplex);
      //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
      if (ccd1.calcTimeOfImpact(col0.getWorldTransform(tmpTrans1), col0.getInterpolationWorldTransform(tmpTrans2),
          col1.getWorldTransform(tmpTrans3), col1.getInterpolationWorldTransform(tmpTrans4), result)) {
        //store result.m_fraction in both bodies

        if (col0.getHitFraction() > result.fraction) {
          col0.setHitFraction(result.fraction);
        }

        if (col1.getHitFraction() > result.fraction) {
          col1.setHitFraction(result.fraction);
        }

        if (resultFraction > result.fraction) {
          resultFraction = result.fraction;
        }

      }
    }

    return resultFraction;
  }

  @Override
  public void getAllContactManifolds(ObjectArrayList<PersistentManifold> manifoldArray) {
    // should we use ownManifold to avoid adding duplicates?
    if (manifoldPtr != null && ownManifold) {
      manifoldArray.add(manifoldPtr);
    }
  }
 
  public PersistentManifold getManifold() {
    return manifoldPtr;
  }
 
  ////////////////////////////////////////////////////////////////////////////
 
  public static class CreateFunc extends CollisionAlgorithmCreateFunc {
    private final ObjectPool<ConvexConvexAlgorithm> pool = ObjectPool.get(ConvexConvexAlgorithm.class);

    public ConvexPenetrationDepthSolver pdSolver;
    public SimplexSolverInterface simplexSolver;

    public CreateFunc(SimplexSolverInterface simplexSolver, ConvexPenetrationDepthSolver pdSolver) {
      this.simplexSolver = simplexSolver;
      this.pdSolver = pdSolver;
    }

    @Override
    public CollisionAlgorithm createCollisionAlgorithm(CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1) {
      ConvexConvexAlgorithm algo = pool.get();
      algo.init(ci.manifold, ci, body0, body1, simplexSolver, pdSolver);
      return algo;
    }

    @Override
    public void releaseCollisionAlgorithm(CollisionAlgorithm algo) {
      pool.release((ConvexConvexAlgorithm)algo);
    }
  }
 
}
TOP

Related Classes of com.bulletphysics.collision.dispatch.ConvexConvexAlgorithm$CreateFunc

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.