|
|
@ -106,93 +106,83 @@ namespace Resource
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BulletShapeManager::~BulletShapeManager() {}
|
|
|
|
BulletShapeManager::~BulletShapeManager() = default;
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<const BulletShape> BulletShapeManager::getShape(const std::string& name)
|
|
|
|
osg::ref_ptr<const BulletShape> BulletShapeManager::getShape(VFS::Path::NormalizedView name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const VFS::Path::Normalized normalized(name);
|
|
|
|
if (osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(name))
|
|
|
|
|
|
|
|
return osg::ref_ptr<BulletShape>(static_cast<BulletShape*>(obj.get()));
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<BulletShape> shape;
|
|
|
|
osg::ref_ptr<BulletShape> shape;
|
|
|
|
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(normalized);
|
|
|
|
|
|
|
|
if (obj)
|
|
|
|
if (Misc::getFileExtension(name.value()) == "nif")
|
|
|
|
shape = osg::ref_ptr<BulletShape>(static_cast<BulletShape*>(obj.get()));
|
|
|
|
{
|
|
|
|
|
|
|
|
NifBullet::BulletNifLoader loader;
|
|
|
|
|
|
|
|
shape = loader.load(*mNifFileManager->get(name));
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (Misc::getFileExtension(normalized) == "nif")
|
|
|
|
// TODO: support .bullet shape files
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<const osg::Node> constNode(mSceneManager->getTemplate(name));
|
|
|
|
|
|
|
|
// const-trickery required because there is no const version of NodeVisitor
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> node(const_cast<osg::Node*>(constNode.get()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check first if there's a custom collision node
|
|
|
|
|
|
|
|
unsigned int visitAllNodesMask = 0xffffffff;
|
|
|
|
|
|
|
|
SceneUtil::FindByNameVisitor nameFinder("Collision");
|
|
|
|
|
|
|
|
nameFinder.setTraversalMask(visitAllNodesMask);
|
|
|
|
|
|
|
|
nameFinder.setNodeMaskOverride(visitAllNodesMask);
|
|
|
|
|
|
|
|
node->accept(nameFinder);
|
|
|
|
|
|
|
|
if (nameFinder.mFoundNode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
NifBullet::BulletNifLoader loader;
|
|
|
|
NodeToShapeVisitor visitor;
|
|
|
|
shape = loader.load(*mNifFileManager->get(normalized));
|
|
|
|
visitor.setTraversalMask(visitAllNodesMask);
|
|
|
|
|
|
|
|
visitor.setNodeMaskOverride(visitAllNodesMask);
|
|
|
|
|
|
|
|
nameFinder.mFoundNode->accept(visitor);
|
|
|
|
|
|
|
|
shape = visitor.getShape();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
|
|
// Generate a collision shape from the mesh
|
|
|
|
|
|
|
|
if (!shape)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// TODO: support .bullet shape files
|
|
|
|
NodeToShapeVisitor visitor;
|
|
|
|
|
|
|
|
node->accept(visitor);
|
|
|
|
osg::ref_ptr<const osg::Node> constNode(mSceneManager->getTemplate(normalized));
|
|
|
|
shape = visitor.getShape();
|
|
|
|
osg::ref_ptr<osg::Node> node(const_cast<osg::Node*>(
|
|
|
|
|
|
|
|
constNode.get())); // const-trickery required because there is no const version of NodeVisitor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check first if there's a custom collision node
|
|
|
|
|
|
|
|
unsigned int visitAllNodesMask = 0xffffffff;
|
|
|
|
|
|
|
|
SceneUtil::FindByNameVisitor nameFinder("Collision");
|
|
|
|
|
|
|
|
nameFinder.setTraversalMask(visitAllNodesMask);
|
|
|
|
|
|
|
|
nameFinder.setNodeMaskOverride(visitAllNodesMask);
|
|
|
|
|
|
|
|
node->accept(nameFinder);
|
|
|
|
|
|
|
|
if (nameFinder.mFoundNode)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
NodeToShapeVisitor visitor;
|
|
|
|
|
|
|
|
visitor.setTraversalMask(visitAllNodesMask);
|
|
|
|
|
|
|
|
visitor.setNodeMaskOverride(visitAllNodesMask);
|
|
|
|
|
|
|
|
nameFinder.mFoundNode->accept(visitor);
|
|
|
|
|
|
|
|
shape = visitor.getShape();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Generate a collision shape from the mesh
|
|
|
|
|
|
|
|
if (!shape)
|
|
|
|
if (!shape)
|
|
|
|
{
|
|
|
|
return osg::ref_ptr<BulletShape>();
|
|
|
|
NodeToShapeVisitor visitor;
|
|
|
|
|
|
|
|
node->accept(visitor);
|
|
|
|
|
|
|
|
shape = visitor.getShape();
|
|
|
|
|
|
|
|
if (!shape)
|
|
|
|
|
|
|
|
return osg::ref_ptr<BulletShape>();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (shape != nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
shape->mFileName = normalized;
|
|
|
|
|
|
|
|
constNode->getUserValue(Misc::OsgUserValues::sFileHash, shape->mFileHash);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mCache->addEntryToObjectCache(normalized, shape);
|
|
|
|
if (shape != nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
shape->mFileName = name;
|
|
|
|
|
|
|
|
constNode->getUserValue(Misc::OsgUserValues::sFileHash, shape->mFileHash);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mCache->addEntryToObjectCache(name.value(), shape);
|
|
|
|
|
|
|
|
|
|
|
|
return shape;
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<BulletShapeInstance> BulletShapeManager::cacheInstance(const std::string& name)
|
|
|
|
osg::ref_ptr<BulletShapeInstance> BulletShapeManager::cacheInstance(VFS::Path::NormalizedView name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const std::string normalized = VFS::Path::normalizeFilename(name);
|
|
|
|
osg::ref_ptr<BulletShapeInstance> instance = createInstance(name);
|
|
|
|
|
|
|
|
if (instance != nullptr)
|
|
|
|
osg::ref_ptr<BulletShapeInstance> instance = createInstance(normalized);
|
|
|
|
mInstanceCache->addEntryToObjectCache(name, instance.get());
|
|
|
|
if (instance)
|
|
|
|
|
|
|
|
mInstanceCache->addEntryToObjectCache(normalized, instance.get());
|
|
|
|
|
|
|
|
return instance;
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<BulletShapeInstance> BulletShapeManager::getInstance(const std::string& name)
|
|
|
|
osg::ref_ptr<BulletShapeInstance> BulletShapeManager::getInstance(VFS::Path::NormalizedView name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const std::string normalized = VFS::Path::normalizeFilename(name);
|
|
|
|
if (osg::ref_ptr<osg::Object> obj = mInstanceCache->takeFromObjectCache(name))
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Object> obj = mInstanceCache->takeFromObjectCache(normalized);
|
|
|
|
|
|
|
|
if (obj.get())
|
|
|
|
|
|
|
|
return static_cast<BulletShapeInstance*>(obj.get());
|
|
|
|
return static_cast<BulletShapeInstance*>(obj.get());
|
|
|
|
else
|
|
|
|
return createInstance(name);
|
|
|
|
return createInstance(normalized);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<BulletShapeInstance> BulletShapeManager::createInstance(const std::string& name)
|
|
|
|
osg::ref_ptr<BulletShapeInstance> BulletShapeManager::createInstance(VFS::Path::NormalizedView name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
osg::ref_ptr<const BulletShape> shape = getShape(name);
|
|
|
|
if (osg::ref_ptr<const BulletShape> shape = getShape(name))
|
|
|
|
if (shape)
|
|
|
|
|
|
|
|
return makeInstance(std::move(shape));
|
|
|
|
return makeInstance(std::move(shape));
|
|
|
|
return osg::ref_ptr<BulletShapeInstance>();
|
|
|
|
return osg::ref_ptr<BulletShapeInstance>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|