osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif) { mShape = new Resource::BulletShape; mCompoundShape.reset(); mStaticMesh.reset(); mAvoidStaticMesh.reset(); if (nif.numRoots() < 1) { warn("Found no root nodes in NIF."); return mShape; } Nif::Record *r = nif.getRoot(0); assert(r != nullptr); Nif::Node *node = dynamic_cast<Nif::Node*>(r); if (node == nullptr) { warn("First root in file was not a node, but a " + r->recName + ". Skipping file."); return mShape; } if (findBoundingBox(node)) { std::unique_ptr<btCompoundShape> compound (new btCompoundShape); std::unique_ptr<btBoxShape> boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents))); btTransform transform = btTransform::getIdentity(); transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate)); compound->addChildShape(transform, boxShape.get()); boxShape.release(); mShape->mCollisionShape = compound.release(); return mShape; } else { bool autogenerated = hasAutoGeneratedCollision(node); // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource). // assume all nodes in the file will be animated const auto filename = nif.getFilename(); const bool isAnimated = pathFileNameStartsWithX(filename); handleNode(filename, node, 0, autogenerated, isAnimated, autogenerated); if (mCompoundShape) { if (mStaticMesh) { btTransform trans; trans.setIdentity(); std::unique_ptr<btCollisionShape> child(new Resource::TriangleMeshShape(mStaticMesh.get(), true)); mCompoundShape->addChildShape(trans, child.get()); child.release(); mStaticMesh.release(); } mShape->mCollisionShape = mCompoundShape.release(); } else if (mStaticMesh) { mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh.get(), true); mStaticMesh.release(); } if (mAvoidStaticMesh) { mShape->mAvoidCollisionShape = new Resource::TriangleMeshShape(mAvoidStaticMesh.get(), false); mAvoidStaticMesh.release(); } return mShape; } }
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr& nif) { mShape = new Resource::BulletShape; mCompoundShape = NULL; mStaticMesh = NULL; if (nif->numRoots() < 1) { warn("Found no root nodes in NIF."); return mShape; } Nif::Record *r = nif->getRoot(0); assert(r != NULL); Nif::Node *node = dynamic_cast<Nif::Node*>(r); if (node == NULL) { warn("First root in file was not a node, but a " + r->recName + ". Skipping file."); return mShape; } if (findBoundingBox(node)) { std::unique_ptr<btCompoundShape> compound (new btCompoundShape); btBoxShape* boxShape = new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents)); btTransform transform = btTransform::getIdentity(); transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate)); compound->addChildShape(transform, boxShape); mShape->mCollisionShape = compound.release(); return mShape; } else { bool autogenerated = hasAutoGeneratedCollision(node); bool isAnimated = false; // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource). // assume all nodes in the file will be animated std::string filename = nif->getFilename(); size_t slashpos = filename.find_last_of("/\\"); if (slashpos == std::string::npos) slashpos = 0; if (slashpos+1 < filename.size() && (filename[slashpos+1] == 'x' || filename[slashpos+1] == 'X')) { isAnimated = true; } handleNode(node, 0, autogenerated, isAnimated, autogenerated); if (mCompoundShape) { mShape->mCollisionShape = mCompoundShape; if (mStaticMesh) { btTransform trans; trans.setIdentity(); mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh,true)); } } else if (mStaticMesh) mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh,true); return mShape; } }