Package com.bulletphysics.collision.shapes

Source Code of com.bulletphysics.collision.shapes.BvhTriangleMeshShape$MyNodeOverlapCallback

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

import com.bulletphysics.BulletGlobals;
import com.bulletphysics.util.ObjectPool;
import com.bulletphysics.collision.broadphase.BroadphaseNativeType;
import com.bulletphysics.linearmath.VectorUtil;
import cz.advel.stack.Stack;
import javax.vecmath.Vector3f;

/**
* BvhTriangleMeshShape is a static-triangle mesh shape with several optimizations,
* such as bounding volume hierarchy. It is recommended to enable useQuantizedAabbCompression
* for better memory usage.<p>
*
* It takes a triangle mesh as input, for example a {@link TriangleMesh} or
* {@link TriangleIndexVertexArray}. The BvhTriangleMeshShape class allows for
* triangle mesh deformations by a refit or partialRefit method.<p>
*
* Instead of building the bounding volume hierarchy acceleration structure, it is
* also possible to serialize (save) and deserialize (load) the structure from disk.
* See ConcaveDemo for an example.
*
* @author jezek2
*/
public class BvhTriangleMeshShape extends TriangleMeshShape {

  private OptimizedBvh bvh;
  private boolean useQuantizedAabbCompression;
  private boolean ownsBvh;
 
  private ObjectPool<MyNodeOverlapCallback> myNodeCallbacks = ObjectPool.get(MyNodeOverlapCallback.class);
 
  public BvhTriangleMeshShape() {
    super(null);
    this.bvh = null;
    this.ownsBvh = false;
  }

  public BvhTriangleMeshShape(StridingMeshInterface meshInterface, boolean useQuantizedAabbCompression) {
    this(meshInterface, useQuantizedAabbCompression, true);
  }
 
  public BvhTriangleMeshShape(StridingMeshInterface meshInterface, boolean useQuantizedAabbCompression, boolean buildBvh) {
    super(meshInterface);
    this.bvh = null;
    this.useQuantizedAabbCompression = useQuantizedAabbCompression;
    this.ownsBvh = false;

    // construct bvh from meshInterface
    //#ifndef DISABLE_BVH

    Vector3f bvhAabbMin = new Vector3f(), bvhAabbMax = new Vector3f();
    meshInterface.calculateAabbBruteForce(bvhAabbMin, bvhAabbMax);

    if (buildBvh) {
      bvh = new OptimizedBvh();
      bvh.build(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax);
      ownsBvh = true;

      // JAVA NOTE: moved from TriangleMeshShape
      recalcLocalAabb();
    }

    //#endif //DISABLE_BVH
  }

  /**
   * Optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb.
   */
  public BvhTriangleMeshShape(StridingMeshInterface meshInterface, boolean useQuantizedAabbCompression, Vector3f bvhAabbMin, Vector3f bvhAabbMax) {
    this(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, true);
  }
 
  /**
   * Optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb.
   */
  public BvhTriangleMeshShape(StridingMeshInterface meshInterface, boolean useQuantizedAabbCompression, Vector3f bvhAabbMin, Vector3f bvhAabbMax, boolean buildBvh) {
    super(meshInterface);

    this.bvh = null;
    this.useQuantizedAabbCompression = useQuantizedAabbCompression;
    this.ownsBvh = false;

    // construct bvh from meshInterface
    //#ifndef DISABLE_BVH

    if (buildBvh) {
      bvh = new OptimizedBvh();

      bvh.build(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax);
      ownsBvh = true;
    }

    // JAVA NOTE: moved from TriangleMeshShape
    recalcLocalAabb();
    //#endif //DISABLE_BVH
  }

  public boolean getOwnsBvh() {
    return ownsBvh;
  }
 
  @Override
  public BroadphaseNativeType getShapeType() {
    return BroadphaseNativeType.TRIANGLE_MESH_SHAPE_PROXYTYPE;
  }

  public void performRaycast(TriangleCallback callback, Vector3f raySource, Vector3f rayTarget) {
    MyNodeOverlapCallback myNodeCallback = myNodeCallbacks.get();
    myNodeCallback.init(callback, meshInterface);

    bvh.reportRayOverlappingNodex(myNodeCallback, raySource, rayTarget);
   
    myNodeCallbacks.release(myNodeCallback);
  }
 
  public void performConvexcast(TriangleCallback callback, Vector3f raySource, Vector3f rayTarget, Vector3f aabbMin, Vector3f aabbMax) {
    MyNodeOverlapCallback myNodeCallback = myNodeCallbacks.get();
    myNodeCallback.init(callback, meshInterface);

    bvh.reportBoxCastOverlappingNodex(myNodeCallback, raySource, rayTarget, aabbMin, aabbMax);

    myNodeCallbacks.release(myNodeCallback);
  }

  /**
   * Perform bvh tree traversal and report overlapping triangles to 'callback'.
   */
  @Override
  public void processAllTriangles(TriangleCallback callback, Vector3f aabbMin, Vector3f aabbMax) {
    //#ifdef DISABLE_BVH
    // // brute force traverse all triangles
    //btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax);
    //#else

    // first get all the nodes
    MyNodeOverlapCallback myNodeCallback = myNodeCallbacks.get();
    myNodeCallback.init(callback, meshInterface);

    bvh.reportAabbOverlappingNodex(myNodeCallback, aabbMin, aabbMax);

    myNodeCallbacks.release(myNodeCallback);
    //#endif//DISABLE_BVH
  }
 
  public void refitTree(Vector3f aabbMin, Vector3f aabbMax) {
    // JAVA NOTE: update it for 2.70b1
    //bvh.refit(meshInterface, aabbMin, aabbMax);
    bvh.refit(meshInterface);

    recalcLocalAabb();
  }

  /**
   * For a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks.
   */
  public void partialRefitTree(Vector3f aabbMin, Vector3f aabbMax) {
    bvh.refitPartial(meshInterface,aabbMin,aabbMax );

    VectorUtil.setMin(localAabbMin, aabbMin);
    VectorUtil.setMax(localAabbMax, aabbMax);
  }

  @Override
  public String getName() {
    return "BVHTRIANGLEMESH";
  }
 
  @Override
  public void setLocalScaling(Vector3f scaling) {
    Vector3f tmp = Stack.alloc(Vector3f.class);
    tmp.sub(getLocalScaling(Stack.alloc(Vector3f.class)), scaling);

    if (tmp.lengthSquared() > BulletGlobals.SIMD_EPSILON) {
      super.setLocalScaling(scaling);
      /*
      if (ownsBvh)
      {
      m_bvh->~btOptimizedBvh();
      btAlignedFree(m_bvh);
      }
      */
      ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
      bvh = new OptimizedBvh();
      // rebuild the bvh...
      bvh.build(meshInterface, useQuantizedAabbCompression, localAabbMin, localAabbMax);
      ownsBvh = true;
    }
  }
 
  public OptimizedBvh getOptimizedBvh() {
    return bvh;
  }

  public void setOptimizedBvh(OptimizedBvh bvh) {
    Vector3f scaling = Stack.alloc(Vector3f.class);
    scaling.set(1f, 1f, 1f);
    setOptimizedBvh(bvh, scaling);
  }

  public void setOptimizedBvh(OptimizedBvh bvh, Vector3f scaling) {
    assert (this.bvh == null);
    assert (!ownsBvh);

    this.bvh = bvh;
    ownsBvh = false;

    // update the scaling without rebuilding the bvh
    Vector3f tmp = Stack.alloc(Vector3f.class);
    tmp.sub(getLocalScaling(Stack.alloc(Vector3f.class)), scaling);

    if (tmp.lengthSquared() > BulletGlobals.SIMD_EPSILON) {
      super.setLocalScaling(scaling);
    }
  }

  public boolean usesQuantizedAabbCompression() {
    return useQuantizedAabbCompression;
  }
 
  ////////////////////////////////////////////////////////////////////////////
 
  protected static class MyNodeOverlapCallback extends NodeOverlapCallback {
    public StridingMeshInterface meshInterface;
    public TriangleCallback callback;

    private Vector3f[] triangle/*[3]*/ = new Vector3f[] { new Vector3f(), new Vector3f(), new Vector3f() };

    public MyNodeOverlapCallback() {
    }
   
    public void init(TriangleCallback callback, StridingMeshInterface meshInterface) {
      this.meshInterface = meshInterface;
      this.callback = callback;
    }

    public void processNode(int nodeSubPart, int nodeTriangleIndex) {
      VertexData data = meshInterface.getLockedReadOnlyVertexIndexBase(nodeSubPart);

      Vector3f meshScaling = meshInterface.getScaling(Stack.alloc(Vector3f.class));

      data.getTriangle(nodeTriangleIndex*3, meshScaling, triangle);

      /* Perform ray vs. triangle collision here */
      callback.processTriangle(triangle, nodeSubPart, nodeTriangleIndex);
     
      meshInterface.unLockReadOnlyVertexBase(nodeSubPart);
    }
  }
 
}
TOP

Related Classes of com.bulletphysics.collision.shapes.BvhTriangleMeshShape$MyNodeOverlapCallback

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.