void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf &transform, bool isAnimated, bool avoid) { assert(shape != nullptr); // If the object was marked "NCO" earlier, it shouldn't collide with // anything. So don't do anything. if ((flags & 0x800)) { return; } if (!shape->skin.empty()) isAnimated = false; if (shape->data.empty()) return; if (shape->data->triangles.empty()) return; if (isAnimated) { if (!mCompoundShape) mCompoundShape.reset(new btCompoundShape); std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh); fillTriangleMesh(*childMesh, shape->data.get()); std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true)); childMesh.release(); float scale = shape->trafo.scale; const Nif::Node* parent = shape; while (parent->parent) { parent = parent->parent; scale *= parent->trafo.scale; } osg::Quat q = transform.getRotate(); osg::Vec3f v = transform.getTrans(); childShape->setLocalScaling(btVector3(scale, scale, scale)); btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z())); mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes())); mCompoundShape->addChildShape(trans, childShape.get()); childShape.release(); } else if (avoid) { if (!mAvoidStaticMesh) mAvoidStaticMesh.reset(new btTriangleMesh(false)); fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); } else { if (!mStaticMesh) mStaticMesh.reset(new btTriangleMesh(false)); // Static shape, just transform all vertices into position fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform); } }
void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf &transform, bool isAnimated) { assert(shape != NULL); // If the object was marked "NCO" earlier, it shouldn't collide with // anything. So don't do anything. if ((flags & 0x800)) { return; } if (!shape->skin.empty()) isAnimated = false; if (shape->data.empty()) return; if (shape->data->triangles.empty()) return; if (isAnimated) { if (!mCompoundShape) mCompoundShape = new btCompoundShape(); btTriangleMesh* childMesh = new btTriangleMesh(); const Nif::NiTriShapeData *data = shape->data.getPtr(); childMesh->preallocateVertices(data->vertices.size()); childMesh->preallocateIndices(data->triangles.size()); const std::vector<osg::Vec3f> &vertices = data->vertices; const std::vector<unsigned short> &triangles = data->triangles; for(size_t i = 0;i < data->triangles.size();i+=3) { osg::Vec3f b1 = vertices[triangles[i+0]]; osg::Vec3f b2 = vertices[triangles[i+1]]; osg::Vec3f b3 = vertices[triangles[i+2]]; childMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3)); } Resource::TriangleMeshShape* childShape = new Resource::TriangleMeshShape(childMesh,true); float scale = shape->trafo.scale; const Nif::Node* parent = shape; while (parent->parent) { parent = parent->parent; scale *= parent->trafo.scale; } osg::Quat q = transform.getRotate(); osg::Vec3f v = transform.getTrans(); childShape->setLocalScaling(btVector3(scale, scale, scale)); btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z())); mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes())); mCompoundShape->addChildShape(trans, childShape); } else { if (!mStaticMesh) mStaticMesh = new btTriangleMesh(false); // Static shape, just transform all vertices into position const Nif::NiTriShapeData *data = shape->data.getPtr(); const std::vector<osg::Vec3f> &vertices = data->vertices; const std::vector<unsigned short> &triangles = data->triangles; mStaticMesh->preallocateVertices(data->vertices.size()); mStaticMesh->preallocateIndices(data->triangles.size()); size_t numtris = data->triangles.size(); for(size_t i = 0;i < numtris;i+=3) { osg::Vec3f b1 = vertices[triangles[i+0]]*transform; osg::Vec3f b2 = vertices[triangles[i+1]]*transform; osg::Vec3f b3 = vertices[triangles[i+2]]*transform; mStaticMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3)); } } }