mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-25 16:39:43 +00:00
Do not use collision shapes with visual only collision to generate navmesh
These collision shapes are not used for actors movement physics simulation.
This commit is contained in:
parent
649ca6b8e6
commit
01b3938935
12 changed files with 78 additions and 48 deletions
|
@ -304,6 +304,9 @@ namespace NavMeshTool
|
||||||
forEachObject(cell, esmData, vfs, bulletShapeManager, readers,
|
forEachObject(cell, esmData, vfs, bulletShapeManager, readers,
|
||||||
[&] (BulletObject object)
|
[&] (BulletObject object)
|
||||||
{
|
{
|
||||||
|
if (object.getShapeInstance()->mVisualCollisionType != Resource::VisualCollisionType::None)
|
||||||
|
return;
|
||||||
|
|
||||||
const btTransform& transform = object.getCollisionObject().getWorldTransform();
|
const btTransform& transform = object.getCollisionObject().getWorldTransform();
|
||||||
const btAABB aabb = BulletHelpers::getAabb(*object.getCollisionObject().getCollisionShape(), transform);
|
const btAABB aabb = BulletHelpers::getAabb(*object.getCollisionObject().getCollisionShape(), transform);
|
||||||
mergeOrAssign(aabb, navMeshInput.mAabb, navMeshInput.mAabbInitialized);
|
mergeOrAssign(aabb, navMeshInput.mAabb, navMeshInput.mAabbInitialized);
|
||||||
|
|
|
@ -19,7 +19,7 @@ class btConvexShape;
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
class BulletShape;
|
struct BulletShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
|
|
|
@ -489,14 +489,16 @@ namespace MWPhysics
|
||||||
assert(!getObject(ptr));
|
assert(!getObject(ptr));
|
||||||
|
|
||||||
// Override collision type based on shape content.
|
// Override collision type based on shape content.
|
||||||
switch (shapeInstance->mCollisionType)
|
switch (shapeInstance->mVisualCollisionType)
|
||||||
{
|
{
|
||||||
case Resource::BulletShape::CollisionType::Camera:
|
case Resource::VisualCollisionType::None:
|
||||||
collisionType = CollisionType_CameraOnly;
|
|
||||||
break;
|
break;
|
||||||
case Resource::BulletShape::CollisionType::None:
|
case Resource::VisualCollisionType::Default:
|
||||||
collisionType = CollisionType_VisualOnly;
|
collisionType = CollisionType_VisualOnly;
|
||||||
break;
|
break;
|
||||||
|
case Resource::VisualCollisionType::Camera:
|
||||||
|
collisionType = CollisionType_CameraOnly;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto obj = std::make_shared<Object>(ptr, shapeInstance, rotation, collisionType, mTaskScheduler.get());
|
auto obj = std::make_shared<Object>(ptr, shapeInstance, rotation, collisionType, mTaskScheduler.get());
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace osg
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
class BulletShape;
|
struct BulletShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
|
|
|
@ -175,7 +175,7 @@ namespace
|
||||||
transform
|
transform
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else if (object->getShapeInstance()->mVisualCollisionType == Resource::VisualCollisionType::None)
|
||||||
{
|
{
|
||||||
navigator.addObject(
|
navigator.addObject(
|
||||||
DetourNavigator::ObjectId(object),
|
DetourNavigator::ObjectId(object),
|
||||||
|
@ -334,7 +334,8 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
if (const auto object = mPhysics->getObject(ptr))
|
if (const auto object = mPhysics->getObject(ptr))
|
||||||
{
|
{
|
||||||
mNavigator.removeObject(DetourNavigator::ObjectId(object));
|
if (object->getShapeInstance()->mVisualCollisionType == Resource::VisualCollisionType::None)
|
||||||
|
mNavigator.removeObject(DetourNavigator::ObjectId(object));
|
||||||
mPhysics->remove(ptr);
|
mPhysics->remove(ptr);
|
||||||
ptr.mRef->mData.mPhysicsPostponed = false;
|
ptr.mRef->mData.mPhysicsPostponed = false;
|
||||||
}
|
}
|
||||||
|
@ -943,7 +944,8 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getLuaManager()->objectRemovedFromScene(ptr);
|
MWBase::Environment::get().getLuaManager()->objectRemovedFromScene(ptr);
|
||||||
if (const auto object = mPhysics->getObject(ptr))
|
if (const auto object = mPhysics->getObject(ptr))
|
||||||
{
|
{
|
||||||
mNavigator.removeObject(DetourNavigator::ObjectId(object));
|
if (object->getShapeInstance()->mVisualCollisionType == Resource::VisualCollisionType::None)
|
||||||
|
mNavigator.removeObject(DetourNavigator::ObjectId(object));
|
||||||
if (mCurrentCell != nullptr)
|
if (mCurrentCell != nullptr)
|
||||||
{
|
{
|
||||||
const auto player = mWorld.getPlayerPtr();
|
const auto player = mWorld.getPlayerPtr();
|
||||||
|
|
|
@ -1546,6 +1546,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::updateNavigatorObject(const MWPhysics::Object& object)
|
void World::updateNavigatorObject(const MWPhysics::Object& object)
|
||||||
{
|
{
|
||||||
|
if (object.getShapeInstance()->mVisualCollisionType != Resource::VisualCollisionType::None)
|
||||||
|
return;
|
||||||
const MWWorld::Ptr ptr = object.getPtr();
|
const MWWorld::Ptr ptr = object.getPtr();
|
||||||
const DetourNavigator::ObjectShapes shapes(object.getShapeInstance(),
|
const DetourNavigator::ObjectShapes shapes(object.getShapeInstance(),
|
||||||
DetourNavigator::ObjectTransform {ptr.getRefData().getPosition(), ptr.getCellRef().getScale()});
|
DetourNavigator::ObjectTransform {ptr.getRefData().getPosition(), ptr.getCellRef().getScale()});
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -137,13 +138,13 @@ static std::ostream& operator <<(std::ostream& stream, const TriangleMeshShape&
|
||||||
return stream << "}}";
|
return stream << "}}";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool operator ==(const BulletShape::CollisionBox& l, const BulletShape::CollisionBox& r)
|
static bool operator ==(const CollisionBox& l, const CollisionBox& r)
|
||||||
{
|
{
|
||||||
const auto tie = [] (const BulletShape::CollisionBox& v) { return std::tie(v.mExtents, v.mCenter); };
|
const auto tie = [] (const CollisionBox& v) { return std::tie(v.mExtents, v.mCenter); };
|
||||||
return tie(l) == tie(r);
|
return tie(l) == tie(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::ostream& operator <<(std::ostream& stream, const BulletShape::CollisionBox& value)
|
static std::ostream& operator <<(std::ostream& stream, const CollisionBox& value)
|
||||||
{
|
{
|
||||||
return stream << "CollisionBox {" << WriteVec3f {value.mExtents} << ", " << WriteVec3f {value.mCenter} << "}";
|
return stream << "CollisionBox {" << WriteVec3f {value.mExtents} << ", " << WriteVec3f {value.mCenter} << "}";
|
||||||
}
|
}
|
||||||
|
@ -189,18 +190,32 @@ namespace Resource
|
||||||
return compareObjects(lhs.mCollisionShape.get(), rhs.mCollisionShape.get())
|
return compareObjects(lhs.mCollisionShape.get(), rhs.mCollisionShape.get())
|
||||||
&& compareObjects(lhs.mAvoidCollisionShape.get(), rhs.mAvoidCollisionShape.get())
|
&& compareObjects(lhs.mAvoidCollisionShape.get(), rhs.mAvoidCollisionShape.get())
|
||||||
&& lhs.mCollisionBox == rhs.mCollisionBox
|
&& lhs.mCollisionBox == rhs.mCollisionBox
|
||||||
&& lhs.mCollisionType == rhs.mCollisionType
|
&& lhs.mVisualCollisionType == rhs.mVisualCollisionType
|
||||||
&& lhs.mAnimatedShapes == rhs.mAnimatedShapes;
|
&& lhs.mAnimatedShapes == rhs.mAnimatedShapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, Resource::VisualCollisionType value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case Resource::VisualCollisionType::None:
|
||||||
|
return stream << "Resource::VisualCollisionType::None";
|
||||||
|
case Resource::VisualCollisionType::Default:
|
||||||
|
return stream << "Resource::VisualCollisionType::Default";
|
||||||
|
case Resource::VisualCollisionType::Camera:
|
||||||
|
return stream << "Resource::VisualCollisionType::Camera";
|
||||||
|
}
|
||||||
|
return stream << static_cast<std::underlying_type_t<Resource::VisualCollisionType>>(value);
|
||||||
|
}
|
||||||
|
|
||||||
static std::ostream& operator <<(std::ostream& stream, const Resource::BulletShape& value)
|
static std::ostream& operator <<(std::ostream& stream, const Resource::BulletShape& value)
|
||||||
{
|
{
|
||||||
return stream << "Resource::BulletShape {"
|
return stream << "Resource::BulletShape {"
|
||||||
<< value.mCollisionShape.get() << ", "
|
<< value.mCollisionShape.get() << ", "
|
||||||
<< value.mAvoidCollisionShape.get() << ", "
|
<< value.mAvoidCollisionShape.get() << ", "
|
||||||
<< value.mCollisionBox << ", "
|
<< value.mCollisionBox << ", "
|
||||||
<< value.mAnimatedShapes
|
<< value.mAnimatedShapes<< ", "
|
||||||
<< ", collisionType=" << value.mCollisionType
|
<< value.mVisualCollisionType
|
||||||
<< "}";
|
<< "}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1030,7 +1045,7 @@ namespace
|
||||||
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
expected.mCollisionType = Resource::BulletShape::CollisionType::Camera;
|
expected.mVisualCollisionType = Resource::VisualCollisionType::Camera;
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1068,7 @@ namespace
|
||||||
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
expected.mCollisionType = Resource::BulletShape::CollisionType::Camera;
|
expected.mVisualCollisionType = Resource::VisualCollisionType::Camera;
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
@ -1075,7 +1090,7 @@ namespace
|
||||||
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
expected.mCollisionType = Resource::BulletShape::CollisionType::None;
|
expected.mVisualCollisionType = Resource::VisualCollisionType::Default;
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1113,7 @@ namespace
|
||||||
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
expected.mCollisionType = Resource::BulletShape::CollisionType::None;
|
expected.mVisualCollisionType = Resource::VisualCollisionType::Default;
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
@ -1128,7 +1143,7 @@ namespace
|
||||||
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
expected.mCollisionShape.reset(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
expected.mCollisionType = Resource::BulletShape::CollisionType::Camera;
|
expected.mVisualCollisionType = Resource::VisualCollisionType::Camera;
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,9 +223,10 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
|
||||||
bool hasCollisionNode = hasRootCollisionNode(*node);
|
bool hasCollisionNode = hasRootCollisionNode(*node);
|
||||||
bool hasCollisionShape = hasCollisionNode && !collisionShapeIsEmpty(*node);
|
bool hasCollisionShape = hasCollisionNode && !collisionShapeIsEmpty(*node);
|
||||||
if (hasCollisionNode && !hasCollisionShape)
|
if (hasCollisionNode && !hasCollisionShape)
|
||||||
mShape->mCollisionType = Resource::BulletShape::CollisionType::Camera;
|
mShape->mVisualCollisionType = Resource::VisualCollisionType::Camera;
|
||||||
bool generateCollisionShape = !hasCollisionShape;
|
bool generateCollisionShape = !hasCollisionShape;
|
||||||
handleNode(filename, *node, nullptr, 0, generateCollisionShape, isAnimated, generateCollisionShape, false, mShape->mCollisionType);
|
handleNode(filename, *node, nullptr, 0, generateCollisionShape, isAnimated, generateCollisionShape,
|
||||||
|
false, mShape->mVisualCollisionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCompoundShape)
|
if (mCompoundShape)
|
||||||
|
@ -336,7 +337,8 @@ bool BulletNifLoader::collisionShapeIsEmpty(const Nif::Node& rootNode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node& node, const Nif::Parent* parent,
|
void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node& node, const Nif::Parent* parent,
|
||||||
int flags, bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid, unsigned int& collisionType)
|
int flags, bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid,
|
||||||
|
Resource::VisualCollisionType& visualCollisionType)
|
||||||
{
|
{
|
||||||
// TODO: allow on-the fly collision switching via toggling this flag
|
// TODO: allow on-the fly collision switching via toggling this flag
|
||||||
if (node.recType == Nif::RC_NiCollisionSwitch && !node.collisionActive())
|
if (node.recType == Nif::RC_NiCollisionSwitch && !node.collisionActive())
|
||||||
|
@ -344,7 +346,8 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node& n
|
||||||
|
|
||||||
// If RootCollisionNode is empty we treat it as NCC flag and autogenerate collision shape as there was no RootCollisionNode.
|
// If RootCollisionNode is empty we treat it as NCC flag and autogenerate collision shape as there was no RootCollisionNode.
|
||||||
// So ignoring it here if `autogenerated` is true and collisionType was set to `Camera`.
|
// So ignoring it here if `autogenerated` is true and collisionType was set to `Camera`.
|
||||||
if (node.recType == Nif::RC_RootCollisionNode && autogenerated && collisionType == Resource::BulletShape::CollisionType::Camera)
|
if (node.recType == Nif::RC_RootCollisionNode && autogenerated
|
||||||
|
&& visualCollisionType == Resource::VisualCollisionType::Camera)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Accumulate the flags from all the child nodes. This works for all
|
// Accumulate the flags from all the child nodes. This works for all
|
||||||
|
@ -377,10 +380,10 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node& n
|
||||||
// NCC flag in vanilla is partly case sensitive: prefix NC is case insensitive but second C needs be uppercase
|
// NCC flag in vanilla is partly case sensitive: prefix NC is case insensitive but second C needs be uppercase
|
||||||
if (sd->string.length() > 2 && sd->string[2] == 'C')
|
if (sd->string.length() > 2 && sd->string[2] == 'C')
|
||||||
// Collide only with camera.
|
// Collide only with camera.
|
||||||
collisionType = Resource::BulletShape::CollisionType::Camera;
|
visualCollisionType = Resource::VisualCollisionType::Camera;
|
||||||
else
|
else
|
||||||
// No collision.
|
// No collision.
|
||||||
collisionType = Resource::BulletShape::CollisionType::None;
|
visualCollisionType = Resource::VisualCollisionType::Default;
|
||||||
}
|
}
|
||||||
else if (sd->string == "MRK" && autogenerated)
|
else if (sd->string == "MRK" && autogenerated)
|
||||||
{
|
{
|
||||||
|
@ -415,7 +418,7 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node& n
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
assert(std::find(list[i]->parents.begin(), list[i]->parents.end(), ninode) != list[i]->parents.end());
|
assert(std::find(list[i]->parents.begin(), list[i]->parents.end(), ninode) != list[i]->parents.end());
|
||||||
handleNode(fileName, list[i].get(), ¤tParent, flags, isCollisionNode, isAnimated, autogenerated, avoid, collisionType);
|
handleNode(fileName, list[i].get(), ¤tParent, flags, isCollisionNode, isAnimated, autogenerated, avoid, visualCollisionType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,9 @@ public:
|
||||||
private:
|
private:
|
||||||
bool findBoundingBox(const Nif::Node& node, const std::string& filename);
|
bool findBoundingBox(const Nif::Node& node, const std::string& filename);
|
||||||
|
|
||||||
void handleNode(const std::string& fileName, const Nif::Node& node,const Nif::Parent* parent, int flags,
|
void handleNode(const std::string& fileName, const Nif::Node& node, const Nif::Parent* parent, int flags,
|
||||||
bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid, unsigned int& cameraOnlyCollision);
|
bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid,
|
||||||
|
Resource::VisualCollisionType& visualCollisionType);
|
||||||
|
|
||||||
bool hasRootCollisionNode(const Nif::Node& rootNode) const;
|
bool hasRootCollisionNode(const Nif::Node& rootNode) const;
|
||||||
bool collisionShapeIsEmpty(const Nif::Node& rootNode) const;
|
bool collisionShapeIsEmpty(const Nif::Node& rootNode) const;
|
||||||
|
|
|
@ -96,7 +96,7 @@ BulletShapeInstance::BulletShapeInstance(osg::ref_ptr<const BulletShape> source)
|
||||||
{
|
{
|
||||||
mCollisionBox = mSource->mCollisionBox;
|
mCollisionBox = mSource->mCollisionBox;
|
||||||
mAnimatedShapes = mSource->mAnimatedShapes;
|
mAnimatedShapes = mSource->mAnimatedShapes;
|
||||||
mCollisionType = mSource->mCollisionType;
|
mVisualCollisionType = mSource->mVisualCollisionType;
|
||||||
mCollisionShape = duplicateCollisionShape(mSource->mCollisionShape.get());
|
mCollisionShape = duplicateCollisionShape(mSource->mCollisionShape.get());
|
||||||
mAvoidCollisionShape = duplicateCollisionShape(mSource->mAvoidCollisionShape.get());
|
mAvoidCollisionShape = duplicateCollisionShape(mSource->mAvoidCollisionShape.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,22 +27,24 @@ namespace Resource
|
||||||
|
|
||||||
using CollisionShapePtr = std::unique_ptr<btCollisionShape, DeleteCollisionShape>;
|
using CollisionShapePtr = std::unique_ptr<btCollisionShape, DeleteCollisionShape>;
|
||||||
|
|
||||||
class BulletShape : public osg::Object
|
struct CollisionBox
|
||||||
{
|
{
|
||||||
public:
|
osg::Vec3f mExtents;
|
||||||
BulletShape() = default;
|
osg::Vec3f mCenter;
|
||||||
BulletShape(const BulletShape& copy, const osg::CopyOp& copyop);
|
};
|
||||||
|
|
||||||
META_Object(Resource, BulletShape)
|
enum class VisualCollisionType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Default,
|
||||||
|
Camera
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BulletShape : public osg::Object
|
||||||
|
{
|
||||||
CollisionShapePtr mCollisionShape;
|
CollisionShapePtr mCollisionShape;
|
||||||
CollisionShapePtr mAvoidCollisionShape;
|
CollisionShapePtr mAvoidCollisionShape;
|
||||||
|
|
||||||
struct CollisionBox
|
|
||||||
{
|
|
||||||
osg::Vec3f mExtents;
|
|
||||||
osg::Vec3f mCenter;
|
|
||||||
};
|
|
||||||
// Used for actors and projectiles. mCollisionShape is used for actors only when we need to autogenerate collision box for creatures.
|
// Used for actors and projectiles. mCollisionShape is used for actors only when we need to autogenerate collision box for creatures.
|
||||||
// For now, use one file <-> one resource for simplicity.
|
// For now, use one file <-> one resource for simplicity.
|
||||||
CollisionBox mCollisionBox;
|
CollisionBox mCollisionBox;
|
||||||
|
@ -56,16 +58,16 @@ namespace Resource
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
std::string mFileHash;
|
std::string mFileHash;
|
||||||
|
|
||||||
|
VisualCollisionType mVisualCollisionType = VisualCollisionType::None;
|
||||||
|
|
||||||
|
BulletShape() = default;
|
||||||
|
BulletShape(const BulletShape& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
META_Object(Resource, BulletShape)
|
||||||
|
|
||||||
void setLocalScaling(const btVector3& scale);
|
void setLocalScaling(const btVector3& scale);
|
||||||
|
|
||||||
bool isAnimated() const { return !mAnimatedShapes.empty(); }
|
bool isAnimated() const { return !mAnimatedShapes.empty(); }
|
||||||
|
|
||||||
unsigned int mCollisionType = 0;
|
|
||||||
enum CollisionType
|
|
||||||
{
|
|
||||||
None = 0x1,
|
|
||||||
Camera = 0x2
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Resource
|
||||||
class SceneManager;
|
class SceneManager;
|
||||||
class NifFileManager;
|
class NifFileManager;
|
||||||
|
|
||||||
class BulletShape;
|
struct BulletShape;
|
||||||
class BulletShapeInstance;
|
class BulletShapeInstance;
|
||||||
|
|
||||||
class MultiObjectCache;
|
class MultiObjectCache;
|
||||||
|
|
Loading…
Reference in a new issue