Package com.bulletphysics.collision.dispatch

Source Code of com.bulletphysics.collision.dispatch.ManifoldResult

/*
* 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.BulletGlobals;
import com.bulletphysics.util.ObjectPool;
import com.bulletphysics.collision.narrowphase.DiscreteCollisionDetectorInterface;
import com.bulletphysics.collision.narrowphase.ManifoldPoint;
import com.bulletphysics.collision.narrowphase.PersistentManifold;
import com.bulletphysics.linearmath.Transform;
import cz.advel.stack.Stack;
import javax.vecmath.Vector3f;

/**
* ManifoldResult is helper class to manage contact results.
*
* @author jezek2
*/
public class ManifoldResult extends DiscreteCollisionDetectorInterface.Result {

  //protected final BulletStack stack = BulletStack.get();
  protected final ObjectPool<ManifoldPoint> pointsPool = ObjectPool.get(ManifoldPoint.class);
 
  private PersistentManifold manifoldPtr;

  // we need this for compounds
  private final Transform rootTransA = new Transform();
  private final Transform rootTransB = new Transform();
  private CollisionObject body0;
  private CollisionObject body1;
  private int partId0;
  private int partId1;
  private int index0;
  private int index1;

  public ManifoldResult() {
  }

  public ManifoldResult(CollisionObject body0, CollisionObject body1) {
    init(body0, body1);
  }

  public void init(CollisionObject body0, CollisionObject body1) {
    this.body0 = body0;
    this.body1 = body1;
    body0.getWorldTransform(this.rootTransA);
    body1.getWorldTransform(this.rootTransB);
  }

  public PersistentManifold getPersistentManifold() {
    return manifoldPtr;
  }

  public void setPersistentManifold(PersistentManifold manifoldPtr) {
    this.manifoldPtr = manifoldPtr;
  }

  public void setShapeIdentifiers(int partId0, int index0, int partId1, int index1) {
    this.partId0 = partId0;
    this.partId1 = partId1;
    this.index0 = index0;
    this.index1 = index1;
  }

  public void addContactPoint(Vector3f normalOnBInWorld, Vector3f pointInWorld, float depth) {
    assert (manifoldPtr != null);
    //order in manifold needs to match

    if (depth > manifoldPtr.getContactBreakingThreshold()) {
      return;
    }

    boolean isSwapped = manifoldPtr.getBody0() != body0;

    Vector3f pointA = Stack.alloc(Vector3f.class);
    pointA.scaleAdd(depth, normalOnBInWorld, pointInWorld);

    Vector3f localA = Stack.alloc(Vector3f.class);
    Vector3f localB = Stack.alloc(Vector3f.class);

    if (isSwapped) {
      rootTransB.invXform(pointA, localA);
      rootTransA.invXform(pointInWorld, localB);
    }
    else {
      rootTransA.invXform(pointA, localA);
      rootTransB.invXform(pointInWorld, localB);
    }

    ManifoldPoint newPt = pointsPool.get();
    newPt.init(localA, localB, normalOnBInWorld, depth);

    newPt.positionWorldOnA.set(pointA);
    newPt.positionWorldOnB.set(pointInWorld);

    int insertIndex = manifoldPtr.getCacheEntry(newPt);

    newPt.combinedFriction = calculateCombinedFriction(body0, body1);
    newPt.combinedRestitution = calculateCombinedRestitution(body0, body1);

    // BP mod, store contact triangles.
    newPt.partId0 = partId0;
    newPt.partId1 = partId1;
    newPt.index0 = index0;
    newPt.index1 = index1;

    /// todo, check this for any side effects
    if (insertIndex >= 0) {
      //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
      manifoldPtr.replaceContactPoint(newPt, insertIndex);
    }
    else {
      insertIndex = manifoldPtr.addManifoldPoint(newPt);
    }

    // User can override friction and/or restitution
    if (BulletGlobals.getContactAddedCallback() != null &&
        // and if either of the two bodies requires custom material
        ((body0.getCollisionFlags() & CollisionFlags.CUSTOM_MATERIAL_CALLBACK) != 0 ||
        (body1.getCollisionFlags() & CollisionFlags.CUSTOM_MATERIAL_CALLBACK) != 0)) {
      //experimental feature info, for per-triangle material etc.
      CollisionObject obj0 = isSwapped ? body1 : body0;
      CollisionObject obj1 = isSwapped ? body0 : body1;
      BulletGlobals.getContactAddedCallback().contactAdded(manifoldPtr.getContactPoint(insertIndex), obj0, partId0, index0, obj1, partId1, index1);
    }

    pointsPool.release(newPt);
  }

  ///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
  private static float calculateCombinedFriction(CollisionObject body0, CollisionObject body1) {
    float friction = body0.getFriction() * body1.getFriction();

    float MAX_FRICTION = 10f;
    if (friction < -MAX_FRICTION) {
      friction = -MAX_FRICTION;
    }
    if (friction > MAX_FRICTION) {
      friction = MAX_FRICTION;
    }
    return friction;
  }

  private static float calculateCombinedRestitution(CollisionObject body0, CollisionObject body1) {
    return body0.getRestitution() * body1.getRestitution();
  }

  public void refreshContactPoints() {
    assert (manifoldPtr != null);
    if (manifoldPtr.getNumContacts() == 0) {
      return;
    }

    boolean isSwapped = manifoldPtr.getBody0() != body0;

    if (isSwapped) {
      manifoldPtr.refreshContactPoints(rootTransB, rootTransA);
    }
    else {
      manifoldPtr.refreshContactPoints(rootTransA, rootTransB);
    }
  }
}
TOP

Related Classes of com.bulletphysics.collision.dispatch.ManifoldResult

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.