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 }
/** * 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 = new Vector3f(); tmp.sub(getLocalScaling(new Vector3f()), 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 = new Vector3f(); 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 = new Vector3f(); tmp.sub(getLocalScaling(new Vector3f()), 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(new Vector3f()); data.getTriangle(nodeTriangleIndex * 3, meshScaling, triangle); /* Perform ray vs. triangle collision here */ callback.processTriangle(triangle, nodeSubPart, nodeTriangleIndex); meshInterface.unLockReadOnlyVertexBase(nodeSubPart); } } }