All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bulletphysics.collision.shapes.BvhTriangleMeshShape Maven / Gradle / Ivy

The newest version!
/*
 * Java port of Bullet (c) 2008 Martin Dvorak 
 *
 * 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.

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

* * 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 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); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy