123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*
- Bullet Continuous Collision Detection and Physics Library
- Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
- 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.
- */
- #ifndef BT_OBB_BOX_2D_SHAPE_H
- #define BT_OBB_BOX_2D_SHAPE_H
- #include "bullet/BulletCollision//CollisionShapes/btPolyhedralConvexShape.h"
- #include "bullet/BulletCollision//CollisionShapes/btCollisionMargin.h"
- #include "bullet/BulletCollision//BroadphaseCollision/btBroadphaseProxy.h"
- #include "bullet/LinearMath/btVector3.h"
- #include "bullet/LinearMath/btMinMax.h"
- ///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
- ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape
- {
- //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
- btVector3 m_centroid;
- btVector3 m_vertices[4];
- btVector3 m_normals[4];
- public:
- BT_DECLARE_ALIGNED_ALLOCATOR();
- btVector3 getHalfExtentsWithMargin() const
- {
- btVector3 halfExtents = getHalfExtentsWithoutMargin();
- btVector3 margin(getMargin(),getMargin(),getMargin());
- halfExtents += margin;
- return halfExtents;
- }
-
- const btVector3& getHalfExtentsWithoutMargin() const
- {
- return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
- }
-
- virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
- {
- btVector3 halfExtents = getHalfExtentsWithoutMargin();
- btVector3 margin(getMargin(),getMargin(),getMargin());
- halfExtents += margin;
-
- return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
- btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
- btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
- }
- SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
- {
- const btVector3& halfExtents = getHalfExtentsWithoutMargin();
-
- return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
- btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
- btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
- }
- virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
- {
- const btVector3& halfExtents = getHalfExtentsWithoutMargin();
-
- for (int i=0;i<numVectors;i++)
- {
- const btVector3& vec = vectors[i];
- supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
- btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
- btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
- }
- }
- ///a btBox2dShape is a flat 2D box in the X-Y plane (Z extents are zero)
- btBox2dShape( const btVector3& boxHalfExtents)
- : btPolyhedralConvexShape(),
- m_centroid(0,0,0)
- {
- m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
- m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
- m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
- m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);
- m_normals[0].setValue(0,-1,0);
- m_normals[1].setValue(1,0,0);
- m_normals[2].setValue(0,1,0);
- m_normals[3].setValue(-1,0,0);
- btScalar minDimension = boxHalfExtents.getX();
- if (minDimension>boxHalfExtents.getY())
- minDimension = boxHalfExtents.getY();
- setSafeMargin(minDimension);
- m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
- btVector3 margin(getMargin(),getMargin(),getMargin());
- m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
- };
- virtual void setMargin(btScalar collisionMargin)
- {
- //correct the m_implicitShapeDimensions for the margin
- btVector3 oldMargin(getMargin(),getMargin(),getMargin());
- btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
-
- btConvexInternalShape::setMargin(collisionMargin);
- btVector3 newMargin(getMargin(),getMargin(),getMargin());
- m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
- }
- virtual void setLocalScaling(const btVector3& scaling)
- {
- btVector3 oldMargin(getMargin(),getMargin(),getMargin());
- btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
- btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
- btConvexInternalShape::setLocalScaling(scaling);
- m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
- }
- virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
-
- virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
- int getVertexCount() const
- {
- return 4;
- }
- virtual int getNumVertices()const
- {
- return 4;
- }
- const btVector3* getVertices() const
- {
- return &m_vertices[0];
- }
- const btVector3* getNormals() const
- {
- return &m_normals[0];
- }
- virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
- {
- //this plane might not be aligned...
- btVector4 plane ;
- getPlaneEquation(plane,i);
- planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
- planeSupport = localGetSupportingVertex(-planeNormal);
- }
- const btVector3& getCentroid() const
- {
- return m_centroid;
- }
-
- virtual int getNumPlanes() const
- {
- return 6;
- }
-
-
- virtual int getNumEdges() const
- {
- return 12;
- }
- virtual void getVertex(int i,btVector3& vtx) const
- {
- btVector3 halfExtents = getHalfExtentsWithoutMargin();
- vtx = btVector3(
- halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
- halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
- halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
- }
-
- virtual void getPlaneEquation(btVector4& plane,int i) const
- {
- btVector3 halfExtents = getHalfExtentsWithoutMargin();
- switch (i)
- {
- case 0:
- plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
- break;
- case 1:
- plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
- break;
- case 2:
- plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
- break;
- case 3:
- plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
- break;
- case 4:
- plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
- break;
- case 5:
- plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
- break;
- default:
- btAssert(0);
- }
- }
-
- virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
- //virtual void getEdge(int i,Edge& edge) const
- {
- int edgeVert0 = 0;
- int edgeVert1 = 0;
- switch (i)
- {
- case 0:
- edgeVert0 = 0;
- edgeVert1 = 1;
- break;
- case 1:
- edgeVert0 = 0;
- edgeVert1 = 2;
- break;
- case 2:
- edgeVert0 = 1;
- edgeVert1 = 3;
- break;
- case 3:
- edgeVert0 = 2;
- edgeVert1 = 3;
- break;
- case 4:
- edgeVert0 = 0;
- edgeVert1 = 4;
- break;
- case 5:
- edgeVert0 = 1;
- edgeVert1 = 5;
- break;
- case 6:
- edgeVert0 = 2;
- edgeVert1 = 6;
- break;
- case 7:
- edgeVert0 = 3;
- edgeVert1 = 7;
- break;
- case 8:
- edgeVert0 = 4;
- edgeVert1 = 5;
- break;
- case 9:
- edgeVert0 = 4;
- edgeVert1 = 6;
- break;
- case 10:
- edgeVert0 = 5;
- edgeVert1 = 7;
- break;
- case 11:
- edgeVert0 = 6;
- edgeVert1 = 7;
- break;
- default:
- btAssert(0);
- }
- getVertex(edgeVert0,pa );
- getVertex(edgeVert1,pb );
- }
-
- virtual bool isInside(const btVector3& pt,btScalar tolerance) const
- {
- btVector3 halfExtents = getHalfExtentsWithoutMargin();
- //btScalar minDist = 2*tolerance;
-
- bool result = (pt.x() <= (halfExtents.x()+tolerance)) &&
- (pt.x() >= (-halfExtents.x()-tolerance)) &&
- (pt.y() <= (halfExtents.y()+tolerance)) &&
- (pt.y() >= (-halfExtents.y()-tolerance)) &&
- (pt.z() <= (halfExtents.z()+tolerance)) &&
- (pt.z() >= (-halfExtents.z()-tolerance));
-
- return result;
- }
- //debugging
- virtual const char* getName()const
- {
- return "Box2d";
- }
- virtual int getNumPreferredPenetrationDirections() const
- {
- return 6;
- }
-
- virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
- {
- switch (index)
- {
- case 0:
- penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
- break;
- case 1:
- penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
- break;
- case 2:
- penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
- break;
- case 3:
- penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
- break;
- case 4:
- penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
- break;
- case 5:
- penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
- break;
- default:
- btAssert(0);
- }
- }
- };
- #endif //BT_OBB_BOX_2D_SHAPE_H
|