void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) { if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) { btTriangleMeshShape::setLocalScaling(scaling); buildOptimizedBvh(); } }
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. ///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh) :btTriangleMeshShape(meshInterface), m_bvh(0), m_triangleInfoMap(0), m_useQuantizedAabbCompression(useQuantizedAabbCompression), m_ownsBvh(false) { m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; //construct bvh from meshInterface #ifndef DISABLE_BVH if (buildBvh) { buildOptimizedBvh(); } #endif //DISABLE_BVH }
void setCollisionShape(CollisionShape c, const std::string &meshName = "") { if (c == UNDEFINED) return; _meshName = meshName; _reset(); _shapeType = c; btTransform transform; glm::vec3 position = posFromMat4(_entity->getLocalTransform()); glm::vec3 scale = scaleFromMat4(_entity->getLocalTransform()); std::cout << scale.x << " " << scale.y << " " << scale.z << std::endl; glm::vec3 rot = rotFromMat4(_entity->getLocalTransform(), true); transform.setIdentity(); transform.setOrigin(convertGLMVectorToBullet(position)); transform.setRotation(btQuaternion(rot.x, rot.y, rot.z)); _motionState = new btDefaultMotionState(transform); if (c == BOX) { _collisionShape = new btBoxShape(btVector3(0.5, 0.5, 0.5));//new btBoxShape(halfScale); } else if (c == SPHERE) { _collisionShape = new btSphereShape(0.5);//new btSphereShape(scale.x); } else if (c == MESH) { // THERE IS SOME LEAKS BECAUSE THAT'S TEMPORARY SmartPointer<Resources::SharedMesh> mesh = _scene->getEngine().getInstance<Resources::ResourceManager>().getResource(meshName); auto group = new btCompoundShape(); auto &geos = mesh->getGeometry(); for (unsigned int i = 0; i < geos.size(); ++i) { const Resources::Geometry &geo = geos[i]; // DIRTY HACK TEMPORARY // NEED TO REPLACE MESH BY MESH GROUP ! btScalar *t = new btScalar[geo.vertices.size() * 3](); for (unsigned int it = 0; it < geo.vertices.size(); ++it) { t[it * 3] = geo.vertices[it].x; t[it * 3 + 1] = geo.vertices[it].y; t[it * 3 + 2] = geo.vertices[it].z; } btConvexHullShape *tmp = new btConvexHullShape(t, geo.vertices.size(), 3 * sizeof(btScalar)); btShapeHull *hull = new btShapeHull(tmp); btScalar margin = tmp->getMargin(); hull->buildHull(margin); tmp->setUserPointer(hull); btConvexHullShape *s = new btConvexHullShape(); for (int it = 0; it < hull->numVertices(); ++it) { s->addPoint(hull->getVertexPointer()[it], false); } s->recalcLocalAabb(); btTransform localTrans; localTrans.setIdentity(); _collisionShape = s; group->addChildShape(localTrans,s); delete[] t; delete hull; delete tmp; } _collisionShape = group; } else if (c == CONCAVE_STATIC_MESH) // dont work { SmartPointer<Resources::SharedMesh> mesh = _scene->getEngine().getInstance<Resources::ResourceManager>().getResource(meshName); auto trimesh = new btTriangleMesh(); auto &geos = mesh->getGeometry(); for (unsigned int j = 0; j < geos.size(); ++j) { const Resources::Geometry &geo = geos[j]; for (unsigned int i = 2; i < geo.vertices.size(); i += 3) { trimesh->addTriangle(btVector3(geo.vertices[i - 2].x, geo.vertices[i - 2].y, geo.vertices[i - 2].z) , btVector3(geo.vertices[i - 1].x, geo.vertices[i - 1].y, geo.vertices[i - 1].z) , btVector3(geo.vertices[i].x, geo.vertices[i].y, geo.vertices[i].z)); } } auto bvh = new btBvhTriangleMeshShape(trimesh, true); bvh->buildOptimizedBvh(); bool isit = bvh->isConcave(); _collisionShape = bvh; } if (_mass != 0) _collisionShape->calculateLocalInertia(_mass, _inertia); _collisionShape->setLocalScaling(convertGLMVectorToBullet(scale)); _rigidBody = new btRigidBody(_mass, _motionState, _collisionShape, _inertia); _rigidBody->setUserPointer(&_entity); _rigidBody->setAngularFactor(convertGLMVectorToBullet(_rotationConstraint)); _rigidBody->setLinearFactor(convertGLMVectorToBullet(_transformConstraint)); if (_rigidBody->isStaticObject()) { _rigidBody->setActivationState(DISABLE_SIMULATION); } _manager->getWorld()->addRigidBody(_rigidBody); }