mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-21 10:41:33 +00:00
Store copies of ref_ptr for btCollisionShape wrappers in Navigator
To keep btCollisionShape lifetime.
This commit is contained in:
parent
668788a5a2
commit
08b026e907
24 changed files with 276 additions and 198 deletions
|
@ -50,6 +50,10 @@ namespace
|
||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
|
HeightField::HeightField() {}
|
||||||
|
|
||||||
|
HeightField::HeightField(const HeightField&, const osg::CopyOp&) {}
|
||||||
|
|
||||||
HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler)
|
HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler)
|
||||||
: mHoldObject(holdObject)
|
: mHoldObject(holdObject)
|
||||||
#if BT_BULLET_VERSION < 310
|
#if BT_BULLET_VERSION < 310
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define OPENMW_MWPHYSICS_HEIGHTFIELD_H
|
#define OPENMW_MWPHYSICS_HEIGHTFIELD_H
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
#include <osg/Object>
|
||||||
|
|
||||||
#include <LinearMath/btScalar.h>
|
#include <LinearMath/btScalar.h>
|
||||||
|
|
||||||
|
@ -20,12 +21,14 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
class PhysicsTaskScheduler;
|
class PhysicsTaskScheduler;
|
||||||
|
|
||||||
class HeightField
|
class HeightField : public osg::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler);
|
HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler);
|
||||||
~HeightField();
|
~HeightField();
|
||||||
|
|
||||||
|
META_Object(MWPhysics, HeightField)
|
||||||
|
|
||||||
btCollisionObject* getCollisionObject();
|
btCollisionObject* getCollisionObject();
|
||||||
const btCollisionObject* getCollisionObject() const;
|
const btCollisionObject* getCollisionObject() const;
|
||||||
const btHeightfieldTerrainShape* getShape() const;
|
const btHeightfieldTerrainShape* getShape() const;
|
||||||
|
@ -40,6 +43,8 @@ namespace MWPhysics
|
||||||
|
|
||||||
PhysicsTaskScheduler* mTaskScheduler;
|
PhysicsTaskScheduler* mTaskScheduler;
|
||||||
|
|
||||||
|
HeightField();
|
||||||
|
HeightField(const HeightField&, const osg::CopyOp&);
|
||||||
void operator=(const HeightField&);
|
void operator=(const HeightField&);
|
||||||
HeightField(const HeightField&);
|
HeightField(const HeightField&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -443,7 +443,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
||||||
{
|
{
|
||||||
mHeightFields[std::make_pair(x,y)] = std::make_unique<HeightField>(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject, mTaskScheduler.get());
|
mHeightFields[std::make_pair(x,y)] = osg::ref_ptr<HeightField>(new HeightField(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject, mTaskScheduler.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::removeHeightField (int x, int y)
|
void PhysicsSystem::removeHeightField (int x, int y)
|
||||||
|
|
|
@ -276,7 +276,7 @@ namespace MWPhysics
|
||||||
using ProjectileMap = std::map<int, std::shared_ptr<Projectile>>;
|
using ProjectileMap = std::map<int, std::shared_ptr<Projectile>>;
|
||||||
ProjectileMap mProjectiles;
|
ProjectileMap mProjectiles;
|
||||||
|
|
||||||
using HeightFieldMap = std::map<std::pair<int, int>, std::unique_ptr<HeightField>>;
|
using HeightFieldMap = std::map<std::pair<int, int>, osg::ref_ptr<HeightField>>;
|
||||||
HeightFieldMap mHeightFields;
|
HeightFieldMap mHeightFields;
|
||||||
|
|
||||||
bool mDebugDrawEnabled;
|
bool mDebugDrawEnabled;
|
||||||
|
|
|
@ -137,11 +137,9 @@ namespace
|
||||||
{
|
{
|
||||||
if (ptr.getClass().isDoor() && !ptr.getCellRef().getTeleport())
|
if (ptr.getClass().isDoor() && !ptr.getCellRef().getTeleport())
|
||||||
{
|
{
|
||||||
const auto shape = object->getShapeInstance()->getCollisionShape();
|
|
||||||
|
|
||||||
btVector3 aabbMin;
|
btVector3 aabbMin;
|
||||||
btVector3 aabbMax;
|
btVector3 aabbMax;
|
||||||
shape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
|
object->getShapeInstance()->getCollisionShape()->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
|
||||||
|
|
||||||
const auto center = (aabbMax + aabbMin) * 0.5f;
|
const auto center = (aabbMax + aabbMin) * 0.5f;
|
||||||
|
|
||||||
|
@ -168,12 +166,7 @@ namespace
|
||||||
|
|
||||||
navigator.addObject(
|
navigator.addObject(
|
||||||
DetourNavigator::ObjectId(object),
|
DetourNavigator::ObjectId(object),
|
||||||
DetourNavigator::DoorShapes(
|
DetourNavigator::DoorShapes(object->getShapeInstance(), connectionStart, connectionEnd),
|
||||||
*shape,
|
|
||||||
object->getShapeInstance()->getAvoidCollisionShape(),
|
|
||||||
connectionStart,
|
|
||||||
connectionEnd
|
|
||||||
),
|
|
||||||
transform
|
transform
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -181,10 +174,7 @@ namespace
|
||||||
{
|
{
|
||||||
navigator.addObject(
|
navigator.addObject(
|
||||||
DetourNavigator::ObjectId(object),
|
DetourNavigator::ObjectId(object),
|
||||||
DetourNavigator::ObjectShapes {
|
DetourNavigator::ObjectShapes(object->getShapeInstance()),
|
||||||
*object->getShapeInstance()->getCollisionShape(),
|
|
||||||
object->getShapeInstance()->getAvoidCollisionShape()
|
|
||||||
},
|
|
||||||
object->getTransform()
|
object->getTransform()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -400,7 +390,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
|
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
|
||||||
navigator->addObject(DetourNavigator::ObjectId(heightField), *heightField->getShape(),
|
navigator->addObject(DetourNavigator::ObjectId(heightField), heightField, *heightField->getShape(),
|
||||||
heightField->getCollisionObject()->getWorldTransform());
|
heightField->getCollisionObject()->getWorldTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1558,10 +1558,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::updateNavigatorObject(const MWPhysics::Object& object)
|
void World::updateNavigatorObject(const MWPhysics::Object& object)
|
||||||
{
|
{
|
||||||
const DetourNavigator::ObjectShapes shapes {
|
const DetourNavigator::ObjectShapes shapes(object.getShapeInstance());
|
||||||
*object.getShapeInstance()->getCollisionShape(),
|
|
||||||
object.getShapeInstance()->getAvoidCollisionShape()
|
|
||||||
};
|
|
||||||
mShouldUpdateNavigator = mNavigator->updateObject(DetourNavigator::ObjectId(&object), shapes, object.getTransform())
|
mShouldUpdateNavigator = mNavigator->updateObject(DetourNavigator::ObjectId(&object), shapes, object.getTransform())
|
||||||
|| mShouldUpdateNavigator;
|
|| mShouldUpdateNavigator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
#include <components/detournavigator/exceptions.hpp>
|
#include <components/detournavigator/exceptions.hpp>
|
||||||
#include <components/misc/rng.hpp>
|
#include <components/misc/rng.hpp>
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
#include <components/resource/bulletshape.hpp>
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
|
@ -14,6 +17,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
MATCHER_P3(Vec3fEq, x, y, z, "")
|
MATCHER_P3(Vec3fEq, x, y, z, "")
|
||||||
{
|
{
|
||||||
|
@ -80,16 +84,38 @@ namespace
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::size_t size>
|
template <std::size_t size>
|
||||||
btHeightfieldTerrainShape makeSquareHeightfieldTerrainShape(const std::array<btScalar, size>& values,
|
std::unique_ptr<btHeightfieldTerrainShape> makeSquareHeightfieldTerrainShape(const std::array<btScalar, size>& values,
|
||||||
btScalar heightScale = 1, int upAxis = 2, PHY_ScalarType heightDataType = PHY_FLOAT, bool flipQuadEdges = false)
|
btScalar heightScale = 1, int upAxis = 2, PHY_ScalarType heightDataType = PHY_FLOAT, bool flipQuadEdges = false)
|
||||||
{
|
{
|
||||||
const int width = static_cast<int>(std::sqrt(size));
|
const int width = static_cast<int>(std::sqrt(size));
|
||||||
const btScalar min = *std::min_element(values.begin(), values.end());
|
const btScalar min = *std::min_element(values.begin(), values.end());
|
||||||
const btScalar max = *std::max_element(values.begin(), values.end());
|
const btScalar max = *std::max_element(values.begin(), values.end());
|
||||||
const btScalar greater = std::max(std::abs(min), std::abs(max));
|
const btScalar greater = std::max(std::abs(min), std::abs(max));
|
||||||
return btHeightfieldTerrainShape(width, width, values.data(), heightScale, -greater, greater, upAxis, heightDataType, flipQuadEdges);
|
return std::make_unique<btHeightfieldTerrainShape>(width, width, values.data(), heightScale, -greater, greater,
|
||||||
|
upAxis, heightDataType, flipQuadEdges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
osg::ref_ptr<const Resource::BulletShapeInstance> makeBulletShapeInstance(std::unique_ptr<T>&& shape)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<Resource::BulletShape> bulletShape(new Resource::BulletShape);
|
||||||
|
bulletShape->mCollisionShape = std::move(shape).release();
|
||||||
|
return new Resource::BulletShapeInstance(bulletShape);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class CollisionShapeInstance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CollisionShapeInstance(std::unique_ptr<T>&& shape) : mInstance(makeBulletShapeInstance(std::move(shape))) {}
|
||||||
|
|
||||||
|
T& shape() { return static_cast<T&>(*mInstance->mCollisionShape); }
|
||||||
|
const osg::ref_ptr<const Resource::BulletShapeInstance>& instance() const { return mInstance; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<const Resource::BulletShapeInstance> mInstance;
|
||||||
|
};
|
||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
|
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut),
|
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut),
|
||||||
|
@ -122,11 +148,12 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::requiredTilesPresent);
|
mNavigator->wait(mListener, WaitConditionType::requiredTilesPresent);
|
||||||
|
|
||||||
|
@ -167,15 +194,15 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape heightfieldShape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto heightfieldShapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& heightfieldShape = *heightfieldShapePtr;
|
||||||
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
btBoxShape boxShape(btVector3(20, 20, 100));
|
CollisionShapeInstance compound(std::make_unique<btCompoundShape>());
|
||||||
btCompoundShape compoundShape;
|
compound.shape().addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), new btBoxShape(btVector3(20, 20, 100)));
|
||||||
compoundShape.addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), &boxShape);
|
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&heightfieldShape), nullptr, heightfieldShape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -206,7 +233,7 @@ namespace
|
||||||
Vec3fEq(204, -204, 1.99998295307159423828125)
|
Vec3fEq(204, -204, 1.99998295307159423828125)
|
||||||
)) << mPath;
|
)) << mPath;
|
||||||
|
|
||||||
mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -250,16 +277,16 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape heightfieldShape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto heightfieldShapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& heightfieldShape = *heightfieldShapePtr;
|
||||||
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
btBoxShape boxShape(btVector3(20, 20, 100));
|
CollisionShapeInstance compound(std::make_unique<btCompoundShape>());
|
||||||
btCompoundShape compoundShape;
|
compound.shape().addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), new btBoxShape(btVector3(20, 20, 100)));
|
||||||
compoundShape.addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), &boxShape);
|
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&heightfieldShape), nullptr, heightfieldShape, btTransform::getIdentity());
|
||||||
mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -291,9 +318,9 @@ namespace
|
||||||
Vec3fEq(204, -204, 1.99998295307159423828125)
|
Vec3fEq(204, -204, 1.99998295307159423828125)
|
||||||
)) << mPath;
|
)) << mPath;
|
||||||
|
|
||||||
compoundShape.updateChildTransform(0, btTransform(btMatrix3x3::getIdentity(), btVector3(1000, 0, 0)));
|
compound.shape().updateChildTransform(0, btTransform(btMatrix3x3::getIdentity(), btVector3(1000, 0, 0)));
|
||||||
|
|
||||||
mNavigator->updateObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
mNavigator->updateObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -336,7 +363,8 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
const std::array<btScalar, 5 * 5> heightfieldData2 {{
|
const std::array<btScalar, 5 * 5> heightfieldData2 {{
|
||||||
|
@ -346,12 +374,13 @@ namespace
|
||||||
-25, -25, -25, -25, -25,
|
-25, -25, -25, -25, -25,
|
||||||
-25, -25, -25, -25, -25,
|
-25, -25, -25, -25, -25,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape2 = makeSquareHeightfieldTerrainShape(heightfieldData2);
|
const auto shapePtr2 = makeSquareHeightfieldTerrainShape(heightfieldData2);
|
||||||
|
btHeightfieldTerrainShape& shape2 = *shapePtr2;
|
||||||
shape2.setLocalScaling(btVector3(128, 128, 1));
|
shape2.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->addObject(ObjectId(&shape2), shape2, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape2), nullptr, shape2, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -385,6 +414,8 @@ namespace
|
||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, path_should_be_around_avoid_shape)
|
TEST_F(DetourNavigatorNavigatorTest, path_should_be_around_avoid_shape)
|
||||||
{
|
{
|
||||||
|
osg::ref_ptr<Resource::BulletShape> bulletShape(new Resource::BulletShape);
|
||||||
|
|
||||||
std::array<btScalar, 5 * 5> heightfieldData {{
|
std::array<btScalar, 5 * 5> heightfieldData {{
|
||||||
0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0,
|
||||||
0, -25, -25, -25, -25,
|
0, -25, -25, -25, -25,
|
||||||
|
@ -392,8 +423,9 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shapePtr->setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
bulletShape->mCollisionShape = shapePtr.release();
|
||||||
|
|
||||||
std::array<btScalar, 5 * 5> heightfieldDataAvoid {{
|
std::array<btScalar, 5 * 5> heightfieldDataAvoid {{
|
||||||
-25, -25, -25, -25, -25,
|
-25, -25, -25, -25, -25,
|
||||||
|
@ -402,11 +434,14 @@ namespace
|
||||||
-25, -25, -25, -25, -25,
|
-25, -25, -25, -25, -25,
|
||||||
-25, -25, -25, -25, -25,
|
-25, -25, -25, -25, -25,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shapeAvoid = makeSquareHeightfieldTerrainShape(heightfieldDataAvoid);
|
auto shapeAvoidPtr = makeSquareHeightfieldTerrainShape(heightfieldDataAvoid);
|
||||||
shapeAvoid.setLocalScaling(btVector3(128, 128, 1));
|
shapeAvoidPtr->setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
bulletShape->mAvoidCollisionShape = shapeAvoidPtr.release();
|
||||||
|
|
||||||
|
osg::ref_ptr<const Resource::BulletShapeInstance> instance(new Resource::BulletShapeInstance(bulletShape));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), ObjectShapes {shape, &shapeAvoid}, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(instance->getCollisionShape()), ObjectShapes(instance), btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -448,12 +483,13 @@ namespace
|
||||||
-50, -100, -150, -100, -100,
|
-50, -100, -150, -100, -100,
|
||||||
0, -50, -100, -100, -100,
|
0, -50, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, 300, btTransform::getIdentity());
|
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, 300, btTransform::getIdentity());
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -495,12 +531,13 @@ namespace
|
||||||
0, -100, -100, -100, -100, -100, 0,
|
0, -100, -100, -100, -100, -100, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity());
|
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity());
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -541,11 +578,12 @@ namespace
|
||||||
0, -100, -100, -100, -100, -100, 0,
|
0, -100, -100, -100, -100, -100, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->addWater(osg::Vec2i(0, 0), std::numeric_limits<int>::max(), -25, btTransform::getIdentity());
|
mNavigator->addWater(osg::Vec2i(0, 0), std::numeric_limits<int>::max(), -25, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
@ -587,12 +625,13 @@ namespace
|
||||||
0, -100, -100, -100, -100, -100, 0,
|
0, -100, -100, -100, -100, -100, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity());
|
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity());
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -631,11 +670,12 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -643,7 +683,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -684,11 +724,12 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -716,27 +757,29 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape heightfieldShape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto heightfieldShapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& heightfieldShape = *heightfieldShapePtr;
|
||||||
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
const std::vector<btBoxShape> boxShapes(100, btVector3(20, 20, 100));
|
std::vector<CollisionShapeInstance<btBoxShape>> boxes;
|
||||||
|
std::generate_n(std::back_inserter(boxes), 100, [] { return std::make_unique<btBoxShape>(btVector3(20, 20, 100)); });
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
|
|
||||||
mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&heightfieldShape), nullptr, heightfieldShape, btTransform::getIdentity());
|
||||||
|
|
||||||
for (std::size_t i = 0; i < boxShapes.size(); ++i)
|
for (std::size_t i = 0; i < boxes.size(); ++i)
|
||||||
{
|
{
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 10, i * 10, i * 10));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 10, i * 10, i * 10));
|
||||||
mNavigator->addObject(ObjectId(&boxShapes[i]), boxShapes[i], transform);
|
mNavigator->addObject(ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance()), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||||
|
|
||||||
for (std::size_t i = 0; i < boxShapes.size(); ++i)
|
for (std::size_t i = 0; i < boxes.size(); ++i)
|
||||||
{
|
{
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 10 + 1, i * 10 + 1, i * 10 + 1));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 10 + 1, i * 10 + 1, i * 10 + 1));
|
||||||
mNavigator->updateObject(ObjectId(&boxShapes[i]), boxShapes[i], transform);
|
mNavigator->updateObject(ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance()), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
|
@ -773,14 +816,15 @@ namespace
|
||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, update_changed_multiple_times_object_should_delay_navmesh_change)
|
TEST_F(DetourNavigatorNavigatorTest, update_changed_multiple_times_object_should_delay_navmesh_change)
|
||||||
{
|
{
|
||||||
const std::vector<btBoxShape> shapes(100, btVector3(64, 64, 64));
|
std::vector<CollisionShapeInstance<btBoxShape>> shapes;
|
||||||
|
std::generate_n(std::back_inserter(shapes), 100, [] { return std::make_unique<btBoxShape>(btVector3(64, 64, 64)); });
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < shapes.size(); ++i)
|
for (std::size_t i = 0; i < shapes.size(); ++i)
|
||||||
{
|
{
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32, i * 32, i * 32));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32, i * 32, i * 32));
|
||||||
mNavigator->addObject(ObjectId(&shapes[i]), shapes[i], transform);
|
mNavigator->addObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance()), transform);
|
||||||
}
|
}
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
@ -789,7 +833,7 @@ namespace
|
||||||
for (std::size_t i = 0; i < shapes.size(); ++i)
|
for (std::size_t i = 0; i < shapes.size(); ++i)
|
||||||
{
|
{
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32 + 1, i * 32 + 1, i * 32 + 1));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32 + 1, i * 32 + 1, i * 32 + 1));
|
||||||
mNavigator->updateObject(ObjectId(&shapes[i]), shapes[i], transform);
|
mNavigator->updateObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance()), transform);
|
||||||
}
|
}
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
@ -797,7 +841,7 @@ namespace
|
||||||
for (std::size_t i = 0; i < shapes.size(); ++i)
|
for (std::size_t i = 0; i < shapes.size(); ++i)
|
||||||
{
|
{
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32 + 2, i * 32 + 2, i * 32 + 2));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32 + 2, i * 32 + 2, i * 32 + 2));
|
||||||
mNavigator->updateObject(ObjectId(&shapes[i]), shapes[i], transform);
|
mNavigator->updateObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance()), transform);
|
||||||
}
|
}
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
@ -817,11 +861,12 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape shape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto shapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& shape = *shapePtr;
|
||||||
shape.setLocalScaling(btVector3(128, 128, 1));
|
shape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), nullptr, shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
|
||||||
|
@ -840,19 +885,20 @@ namespace
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
0, -25, -100, -100, -100,
|
0, -25, -100, -100, -100,
|
||||||
}};
|
}};
|
||||||
btHeightfieldTerrainShape heightfieldShape = makeSquareHeightfieldTerrainShape(heightfieldData);
|
const auto heightfieldShapePtr = makeSquareHeightfieldTerrainShape(heightfieldData);
|
||||||
|
btHeightfieldTerrainShape& heightfieldShape = *heightfieldShapePtr;
|
||||||
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
heightfieldShape.setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
const btBoxShape oscillatingBoxShape(btVector3(20, 20, 20));
|
CollisionShapeInstance oscillatingBox(std::make_unique<btBoxShape>(btVector3(20, 20, 20)));
|
||||||
const btVector3 oscillatingBoxShapePosition(32, 32, 400);
|
const btVector3 oscillatingBoxShapePosition(32, 32, 400);
|
||||||
const btBoxShape boderBoxShape(btVector3(50, 50, 50));
|
CollisionShapeInstance boderBox(std::make_unique<btBoxShape>(btVector3(50, 50, 50)));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentHalfExtents);
|
mNavigator->addAgent(mAgentHalfExtents);
|
||||||
mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&heightfieldShape), nullptr, heightfieldShape, btTransform::getIdentity());
|
||||||
mNavigator->addObject(ObjectId(&oscillatingBoxShape), oscillatingBoxShape,
|
mNavigator->addObject(ObjectId(&oscillatingBox.shape()), ObjectShapes(oscillatingBox.instance()),
|
||||||
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition));
|
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition));
|
||||||
// add this box to make navmesh bound box independent from oscillatingBoxShape rotations
|
// add this box to make navmesh bound box independent from oscillatingBoxShape rotations
|
||||||
mNavigator->addObject(ObjectId(&boderBoxShape), boderBoxShape,
|
mNavigator->addObject(ObjectId(&boderBox.shape()), ObjectShapes(boderBox.instance()),
|
||||||
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition + btVector3(0, 0, 200)));
|
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition + btVector3(0, 0, 200)));
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
|
@ -869,7 +915,7 @@ namespace
|
||||||
{
|
{
|
||||||
const btTransform transform(btQuaternion(btVector3(0, 0, 1), n * 2 * osg::PI / 10),
|
const btTransform transform(btQuaternion(btVector3(0, 0, 1), n * 2 * osg::PI / 10),
|
||||||
oscillatingBoxShapePosition);
|
oscillatingBoxShapePosition);
|
||||||
mNavigator->updateObject(ObjectId(&oscillatingBoxShape), oscillatingBoxShape, transform);
|
mNavigator->updateObject(ObjectId(&oscillatingBox.shape()), ObjectShapes(oscillatingBox.instance()), transform);
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,22 @@ namespace
|
||||||
|
|
||||||
struct DetourNavigatorRecastMeshObjectTest : Test
|
struct DetourNavigatorRecastMeshObjectTest : Test
|
||||||
{
|
{
|
||||||
btBoxShape mBoxShape {btVector3(1, 2, 3)};
|
btBoxShape mBoxShapeImpl {btVector3(1, 2, 3)};
|
||||||
btCompoundShape mCompoundShape {true};
|
CollisionShape mBoxShape {nullptr, mBoxShapeImpl};
|
||||||
|
btCompoundShape mCompoundShapeImpl {true};
|
||||||
|
CollisionShape mCompoundShape {nullptr, mCompoundShapeImpl};
|
||||||
btTransform mTransform {btQuaternion(btVector3(1, 2, 3), 1), btVector3(1, 2, 3)};
|
btTransform mTransform {btQuaternion(btVector3(1, 2, 3), 1), btVector3(1, 2, 3)};
|
||||||
|
|
||||||
DetourNavigatorRecastMeshObjectTest()
|
DetourNavigatorRecastMeshObjectTest()
|
||||||
{
|
{
|
||||||
mCompoundShape.addChildShape(mTransform, std::addressof(mBoxShape));
|
mCompoundShapeImpl.addChildShape(mTransform, std::addressof(mBoxShapeImpl));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(DetourNavigatorRecastMeshObjectTest, constructed_object_should_have_shape_and_transform)
|
TEST_F(DetourNavigatorRecastMeshObjectTest, constructed_object_should_have_shape_and_transform)
|
||||||
{
|
{
|
||||||
const RecastMeshObject object(mBoxShape, mTransform, AreaType_ground);
|
const RecastMeshObject object(mBoxShape, mTransform, AreaType_ground);
|
||||||
EXPECT_EQ(std::addressof(object.getShape()), std::addressof(mBoxShape));
|
EXPECT_EQ(std::addressof(object.getShape()), std::addressof(mBoxShapeImpl));
|
||||||
EXPECT_EQ(object.getTransform(), mTransform);
|
EXPECT_EQ(object.getTransform(), mTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +60,14 @@ namespace
|
||||||
TEST_F(DetourNavigatorRecastMeshObjectTest, update_for_compound_shape_with_same_transform_and_changed_child_transform_should_return_true)
|
TEST_F(DetourNavigatorRecastMeshObjectTest, update_for_compound_shape_with_same_transform_and_changed_child_transform_should_return_true)
|
||||||
{
|
{
|
||||||
RecastMeshObject object(mCompoundShape, mTransform, AreaType_ground);
|
RecastMeshObject object(mCompoundShape, mTransform, AreaType_ground);
|
||||||
mCompoundShape.updateChildTransform(0, btTransform::getIdentity());
|
mCompoundShapeImpl.updateChildTransform(0, btTransform::getIdentity());
|
||||||
EXPECT_TRUE(object.update(mTransform, AreaType_ground));
|
EXPECT_TRUE(object.update(mTransform, AreaType_ground));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DetourNavigatorRecastMeshObjectTest, repeated_update_for_compound_shape_without_changes_should_return_false)
|
TEST_F(DetourNavigatorRecastMeshObjectTest, repeated_update_for_compound_shape_without_changes_should_return_false)
|
||||||
{
|
{
|
||||||
RecastMeshObject object(mCompoundShape, mTransform, AreaType_ground);
|
RecastMeshObject object(mCompoundShape, mTransform, AreaType_ground);
|
||||||
mCompoundShape.updateChildTransform(0, btTransform::getIdentity());
|
mCompoundShapeImpl.updateChildTransform(0, btTransform::getIdentity());
|
||||||
object.update(mTransform, AreaType_ground);
|
object.update(mTransform, AreaType_ground);
|
||||||
EXPECT_FALSE(object.update(mTransform, AreaType_ground));
|
EXPECT_FALSE(object.update(mTransform, AreaType_ground));
|
||||||
}
|
}
|
||||||
|
@ -73,7 +75,7 @@ namespace
|
||||||
TEST_F(DetourNavigatorRecastMeshObjectTest, update_for_changed_local_scaling_should_return_true)
|
TEST_F(DetourNavigatorRecastMeshObjectTest, update_for_changed_local_scaling_should_return_true)
|
||||||
{
|
{
|
||||||
RecastMeshObject object(mBoxShape, mTransform, AreaType_ground);
|
RecastMeshObject object(mBoxShape, mTransform, AreaType_ground);
|
||||||
mBoxShape.setLocalScaling(btVector3(2, 2, 2));
|
mBoxShapeImpl.setLocalScaling(btVector3(2, 2, 2));
|
||||||
EXPECT_TRUE(object.update(mTransform, AreaType_ground));
|
EXPECT_TRUE(object.update(mTransform, AreaType_ground));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,22 +62,25 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
EXPECT_TRUE(manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
EXPECT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_for_existing_object_should_return_false)
|
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_for_existing_object_should_return_false)
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
EXPECT_FALSE(manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
|
EXPECT_FALSE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_should_add_tiles)
|
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_should_add_tiles)
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||||
for (int x = -1; x < 1; ++x)
|
for (int x = -1; x < 1; ++x)
|
||||||
for (int y = -1; y < 1; ++y)
|
for (int y = -1; y < 1; ++y)
|
||||||
ASSERT_TRUE(manager.hasTile(TilePosition(x, y)));
|
ASSERT_TRUE(manager.hasTile(TilePosition(x, y)));
|
||||||
|
@ -88,8 +91,9 @@ namespace
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, transform, AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
EXPECT_TRUE(manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground,
|
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||||
|
EXPECT_TRUE(manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground,
|
||||||
[&] (const auto& v) { onChangedTile(v); }));
|
[&] (const auto& v) { onChangedTile(v); }));
|
||||||
EXPECT_THAT(
|
EXPECT_THAT(
|
||||||
mChangedTiles,
|
mChangedTiles,
|
||||||
|
@ -102,8 +106,9 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
EXPECT_FALSE(manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground,
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
|
EXPECT_FALSE(manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground,
|
||||||
[&] (const auto& v) { onChangedTile(v); }));
|
[&] (const auto& v) { onChangedTile(v); }));
|
||||||
EXPECT_EQ(mChangedTiles, std::vector<TilePosition>());
|
EXPECT_EQ(mChangedTiles, std::vector<TilePosition>());
|
||||||
}
|
}
|
||||||
|
@ -112,7 +117,8 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
||||||
|
@ -123,7 +129,8 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(1, 0)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(1, 0)), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,14 +139,15 @@ namespace
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||||
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, transform, AreaType::AreaType_ground);
|
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, 0)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(1, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(1, 0)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(1, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(1, -1)), nullptr);
|
||||||
|
|
||||||
manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
||||||
|
@ -151,12 +159,13 @@ namespace
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||||
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, transform, AreaType::AreaType_ground);
|
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||||
|
|
||||||
manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(1, 0)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(1, 0)), nullptr);
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(1, -1)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(1, -1)), nullptr);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +174,8 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
manager.removeObject(ObjectId(&boxShape));
|
manager.removeObject(ObjectId(&boxShape));
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||||
EXPECT_EQ(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
EXPECT_EQ(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||||
|
@ -177,14 +187,15 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, 0)), nullptr);
|
||||||
|
|
||||||
manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||||
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
||||||
|
@ -196,7 +207,8 @@ namespace
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const auto initialRevision = manager.getRevision();
|
const auto initialRevision = manager.getRevision();
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
EXPECT_EQ(manager.getRevision(), initialRevision + 1);
|
EXPECT_EQ(manager.getRevision(), initialRevision + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,9 +216,10 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
const auto beforeAddRevision = manager.getRevision();
|
const auto beforeAddRevision = manager.getRevision();
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
EXPECT_EQ(manager.getRevision(), beforeAddRevision);
|
EXPECT_EQ(manager.getRevision(), beforeAddRevision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,9 +228,10 @@ namespace
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, transform, AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||||
const auto beforeUpdateRevision = manager.getRevision();
|
const auto beforeUpdateRevision = manager.getRevision();
|
||||||
manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||||
EXPECT_EQ(manager.getRevision(), beforeUpdateRevision + 1);
|
EXPECT_EQ(manager.getRevision(), beforeUpdateRevision + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +239,10 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
const auto beforeUpdateRevision = manager.getRevision();
|
const auto beforeUpdateRevision = manager.getRevision();
|
||||||
manager.updateObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||||
EXPECT_EQ(manager.getRevision(), beforeUpdateRevision);
|
EXPECT_EQ(manager.getRevision(), beforeUpdateRevision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +250,8 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||||
const auto beforeRemoveRevision = manager.getRevision();
|
const auto beforeRemoveRevision = manager.getRevision();
|
||||||
manager.removeObject(ObjectId(&boxShape));
|
manager.removeObject(ObjectId(&boxShape));
|
||||||
EXPECT_EQ(manager.getRevision(), beforeRemoveRevision + 1);
|
EXPECT_EQ(manager.getRevision(), beforeRemoveRevision + 1);
|
||||||
|
@ -272,7 +288,8 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||||
const osg::Vec2i cellPosition(0, 0);
|
const osg::Vec2i cellPosition(0, 0);
|
||||||
const int cellSize = std::numeric_limits<int>::max();
|
const int cellSize = std::numeric_limits<int>::max();
|
||||||
ASSERT_TRUE(manager.addWater(cellPosition, cellSize, btTransform::getIdentity()));
|
ASSERT_TRUE(manager.addWater(cellPosition, cellSize, btTransform::getIdentity()));
|
||||||
|
@ -314,7 +331,8 @@ namespace
|
||||||
{
|
{
|
||||||
TileCachedRecastMeshManager manager(mSettings);
|
TileCachedRecastMeshManager manager(mSettings);
|
||||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), boxShape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
const CollisionShape shape(nullptr, boxShape);
|
||||||
|
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||||
const osg::Vec2i cellPosition(0, 0);
|
const osg::Vec2i cellPosition(0, 0);
|
||||||
const int cellSize = 8192;
|
const int cellSize = 8192;
|
||||||
ASSERT_TRUE(manager.addWater(cellPosition, cellSize, btTransform::getIdentity()));
|
ASSERT_TRUE(manager.addWater(cellPosition, cellSize, btTransform::getIdentity()));
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace DetourNavigator
|
||||||
: mImpl(settings, bounds, generation)
|
: mImpl(settings, bounds, generation)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool CachedRecastMeshManager::addObject(const ObjectId id, const btCollisionShape& shape,
|
bool CachedRecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape,
|
||||||
const btTransform& transform, const AreaType areaType)
|
const btTransform& transform, const AreaType areaType)
|
||||||
{
|
{
|
||||||
if (!mImpl.addObject(id, shape, transform, areaType))
|
if (!mImpl.addObject(id, shape, transform, areaType))
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace DetourNavigator
|
||||||
public:
|
public:
|
||||||
CachedRecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation);
|
CachedRecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation);
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType);
|
const AreaType areaType);
|
||||||
|
|
||||||
bool updateObject(const ObjectId id, const btTransform& transform, const AreaType areaType);
|
bool updateObject(const ObjectId id, const btTransform& transform, const AreaType areaType);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "recastmeshtiles.hpp"
|
#include "recastmeshtiles.hpp"
|
||||||
#include "waitconditiontype.hpp"
|
#include "waitconditiontype.hpp"
|
||||||
|
|
||||||
|
#include <components/resource/bulletshape.hpp>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct Cell;
|
struct Cell;
|
||||||
|
@ -24,11 +26,10 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
struct ObjectShapes
|
struct ObjectShapes
|
||||||
{
|
{
|
||||||
const btCollisionShape& mShape;
|
osg::ref_ptr<const Resource::BulletShapeInstance> mShapeInstance;
|
||||||
const btCollisionShape* mAvoid;
|
|
||||||
|
|
||||||
ObjectShapes(const btCollisionShape& shape, const btCollisionShape* avoid)
|
ObjectShapes(const osg::ref_ptr<const Resource::BulletShapeInstance>& shapeInstance)
|
||||||
: mShape(shape), mAvoid(avoid)
|
: mShapeInstance(shapeInstance)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,9 +38,9 @@ namespace DetourNavigator
|
||||||
osg::Vec3f mConnectionStart;
|
osg::Vec3f mConnectionStart;
|
||||||
osg::Vec3f mConnectionEnd;
|
osg::Vec3f mConnectionEnd;
|
||||||
|
|
||||||
DoorShapes(const btCollisionShape& shape, const btCollisionShape* avoid,
|
DoorShapes(const osg::ref_ptr<const Resource::BulletShapeInstance>& shapeInstance,
|
||||||
const osg::Vec3f& connectionStart,const osg::Vec3f& connectionEnd)
|
const osg::Vec3f& connectionStart,const osg::Vec3f& connectionEnd)
|
||||||
: ObjectShapes(shape, avoid)
|
: ObjectShapes(shapeInstance)
|
||||||
, mConnectionStart(connectionStart)
|
, mConnectionStart(connectionStart)
|
||||||
, mConnectionEnd(connectionEnd)
|
, mConnectionEnd(connectionEnd)
|
||||||
{}
|
{}
|
||||||
|
@ -70,13 +71,15 @@ namespace DetourNavigator
|
||||||
virtual void removeAgent(const osg::Vec3f& agentHalfExtents) = 0;
|
virtual void removeAgent(const osg::Vec3f& agentHalfExtents) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief addObject is used to add object represented by single btCollisionShape and btTransform.
|
* @brief addObject is used to add object represented by single btHeightfieldTerrainShape and btTransform.
|
||||||
* @param id is used to distinguish different objects.
|
* @param id is used to distinguish different objects.
|
||||||
* @param shape must live until object is updated by another shape removed from Navigator.
|
* @param holder shape wrapper to keep shape lifetime after object is removed.
|
||||||
|
* @param shape must be wrapped by holder.
|
||||||
* @param transform allows to setup object geometry according to its world state.
|
* @param transform allows to setup object geometry according to its world state.
|
||||||
* @return true if object is added, false if there is already object with given id.
|
* @return true if object is added, false if there is already object with given id.
|
||||||
*/
|
*/
|
||||||
virtual bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) = 0;
|
virtual bool addObject(const ObjectId id, const osg::ref_ptr<const osg::Object>& holder,
|
||||||
|
const btHeightfieldTerrainShape& shape, const btTransform& transform) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief addObject is used to add complex object with allowed to walk and avoided to walk shapes
|
* @brief addObject is used to add complex object with allowed to walk and avoided to walk shapes
|
||||||
|
@ -96,15 +99,6 @@ namespace DetourNavigator
|
||||||
*/
|
*/
|
||||||
virtual bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) = 0;
|
virtual bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief updateObject replace object geometry by given data.
|
|
||||||
* @param id is used to find object.
|
|
||||||
* @param shape must live until object is updated by another shape removed from Navigator.
|
|
||||||
* @param transform allows to setup objects geometry according to its world state.
|
|
||||||
* @return true if object is updated, false if there is no object with given id.
|
|
||||||
*/
|
|
||||||
virtual bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief updateObject replace object geometry by given data.
|
* @brief updateObject replace object geometry by given data.
|
||||||
* @param id is used to find object.
|
* @param id is used to find object.
|
||||||
|
|
|
@ -31,18 +31,22 @@ namespace DetourNavigator
|
||||||
--it->second;
|
--it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavigatorImpl::addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform)
|
bool NavigatorImpl::addObject(const ObjectId id, const osg::ref_ptr<const osg::Object>& holder,
|
||||||
|
const btHeightfieldTerrainShape& shape, const btTransform& transform)
|
||||||
{
|
{
|
||||||
return mNavMeshManager.addObject(id, shape, transform, AreaType_ground);
|
const CollisionShape collisionShape {holder, shape};
|
||||||
|
return mNavMeshManager.addObject(id, collisionShape, transform, AreaType_ground);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavigatorImpl::addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform)
|
bool NavigatorImpl::addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform)
|
||||||
{
|
{
|
||||||
bool result = addObject(id, shapes.mShape, transform);
|
const CollisionShape collisionShape {shapes.mShapeInstance, *shapes.mShapeInstance->getCollisionShape()};
|
||||||
if (shapes.mAvoid)
|
bool result = mNavMeshManager.addObject(id, collisionShape, transform, AreaType_ground);
|
||||||
|
if (const btCollisionShape* const avoidShape = shapes.mShapeInstance->getAvoidCollisionShape())
|
||||||
{
|
{
|
||||||
const ObjectId avoidId(shapes.mAvoid);
|
const ObjectId avoidId(avoidShape);
|
||||||
if (mNavMeshManager.addObject(avoidId, *shapes.mAvoid, transform, AreaType_null))
|
const CollisionShape collisionShape {shapes.mShapeInstance, *avoidShape};
|
||||||
|
if (mNavMeshManager.addObject(avoidId, collisionShape, transform, AreaType_null))
|
||||||
{
|
{
|
||||||
updateAvoidShapeId(id, avoidId);
|
updateAvoidShapeId(id, avoidId);
|
||||||
result = true;
|
result = true;
|
||||||
|
@ -64,18 +68,15 @@ namespace DetourNavigator
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavigatorImpl::updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform)
|
|
||||||
{
|
|
||||||
return mNavMeshManager.updateObject(id, shape, transform, AreaType_ground);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NavigatorImpl::updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform)
|
bool NavigatorImpl::updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform)
|
||||||
{
|
{
|
||||||
bool result = updateObject(id, shapes.mShape, transform);
|
const CollisionShape collisionShape {shapes.mShapeInstance, *shapes.mShapeInstance->getCollisionShape()};
|
||||||
if (shapes.mAvoid)
|
bool result = mNavMeshManager.updateObject(id, collisionShape, transform, AreaType_ground);
|
||||||
|
if (const btCollisionShape* const avoidShape = shapes.mShapeInstance->getAvoidCollisionShape())
|
||||||
{
|
{
|
||||||
const ObjectId avoidId(shapes.mAvoid);
|
const ObjectId avoidId(avoidShape);
|
||||||
if (mNavMeshManager.updateObject(avoidId, *shapes.mAvoid, transform, AreaType_null))
|
const CollisionShape collisionShape {shapes.mShapeInstance, *avoidShape};
|
||||||
|
if (mNavMeshManager.updateObject(avoidId, collisionShape, transform, AreaType_null))
|
||||||
{
|
{
|
||||||
updateAvoidShapeId(id, avoidId);
|
updateAvoidShapeId(id, avoidId);
|
||||||
result = true;
|
result = true;
|
||||||
|
|
|
@ -21,14 +21,13 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void removeAgent(const osg::Vec3f& agentHalfExtents) override;
|
void removeAgent(const osg::Vec3f& agentHalfExtents) override;
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) override;
|
bool addObject(const ObjectId id, const osg::ref_ptr<const osg::Object>& holder,
|
||||||
|
const btHeightfieldTerrainShape& shape, const btTransform& transform) override;
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) override;
|
bool addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) override;
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) override;
|
bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) override;
|
||||||
|
|
||||||
bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) override;
|
|
||||||
|
|
||||||
bool updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) override;
|
bool updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) override;
|
||||||
|
|
||||||
bool updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) override;
|
bool updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) override;
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void removeAgent(const osg::Vec3f& /*agentHalfExtents*/) override {}
|
void removeAgent(const osg::Vec3f& /*agentHalfExtents*/) override {}
|
||||||
|
|
||||||
bool addObject(const ObjectId /*id*/, const btCollisionShape& /*shape*/, const btTransform& /*transform*/) override
|
bool addObject(const ObjectId /*id*/, const osg::ref_ptr<const osg::Object>& /*holder*/,
|
||||||
|
const btHeightfieldTerrainShape& /*shape*/, const btTransform& /*transform*/) override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -34,11 +35,6 @@ namespace DetourNavigator
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateObject(const ObjectId /*id*/, const btCollisionShape& /*shape*/, const btTransform& /*transform*/) override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool updateObject(const ObjectId /*id*/, const ObjectShapes& /*shapes*/, const btTransform& /*transform*/) override
|
bool updateObject(const ObjectId /*id*/, const ObjectShapes& /*shapes*/, const btTransform& /*transform*/) override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -47,16 +47,17 @@ namespace DetourNavigator
|
||||||
, mAsyncNavMeshUpdater(settings, mRecastMeshManager, mOffMeshConnectionsManager)
|
, mAsyncNavMeshUpdater(settings, mRecastMeshManager, mOffMeshConnectionsManager)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool NavMeshManager::addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool NavMeshManager::addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType)
|
const AreaType areaType)
|
||||||
{
|
{
|
||||||
|
const btCollisionShape& collisionShape = shape.getShape();
|
||||||
if (!mRecastMeshManager.addObject(id, shape, transform, areaType))
|
if (!mRecastMeshManager.addObject(id, shape, transform, areaType))
|
||||||
return false;
|
return false;
|
||||||
addChangedTiles(shape, transform, ChangeType::add);
|
addChangedTiles(collisionShape, transform, ChangeType::add);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavMeshManager::updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool NavMeshManager::updateObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType)
|
const AreaType areaType)
|
||||||
{
|
{
|
||||||
return mRecastMeshManager.updateObject(id, shape, transform, areaType,
|
return mRecastMeshManager.updateObject(id, shape, transform, areaType,
|
||||||
|
|
|
@ -23,10 +23,10 @@ namespace DetourNavigator
|
||||||
public:
|
public:
|
||||||
NavMeshManager(const Settings& settings);
|
NavMeshManager(const Settings& settings);
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType);
|
const AreaType areaType);
|
||||||
|
|
||||||
bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool updateObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType);
|
const AreaType areaType);
|
||||||
|
|
||||||
bool removeObject(const ObjectId id);
|
bool removeObject(const ObjectId id);
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecastMeshManager::addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool RecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType)
|
const AreaType areaType)
|
||||||
{
|
{
|
||||||
const auto object = mObjects.lower_bound(id);
|
const auto object = mObjects.lower_bound(id);
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace DetourNavigator
|
||||||
|
|
||||||
RecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation);
|
RecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation);
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType);
|
const AreaType areaType);
|
||||||
|
|
||||||
bool updateObject(const ObjectId id, const btTransform& transform, const AreaType areaType);
|
bool updateObject(const ObjectId id, const btTransform& transform, const AreaType areaType);
|
||||||
|
|
|
@ -22,15 +22,36 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<RecastMeshObject> makeChildrenObjects(const osg::ref_ptr<const osg::Object>& holder,
|
||||||
|
const btCompoundShape& shape, const AreaType areaType)
|
||||||
|
{
|
||||||
|
std::vector<RecastMeshObject> result;
|
||||||
|
for (int i = 0, num = shape.getNumChildShapes(); i < num; ++i)
|
||||||
|
{
|
||||||
|
const CollisionShape collisionShape {holder, *shape.getChildShape(i)};
|
||||||
|
result.emplace_back(collisionShape, shape.getChildTransform(i), areaType);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RecastMeshObject> makeChildrenObjects(const osg::ref_ptr<const osg::Object>& holder,
|
||||||
|
const btCollisionShape& shape, const AreaType areaType)
|
||||||
|
{
|
||||||
|
if (shape.isCompound())
|
||||||
|
return makeChildrenObjects(holder, static_cast<const btCompoundShape&>(shape), areaType);
|
||||||
|
return std::vector<RecastMeshObject>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RecastMeshObject::RecastMeshObject(const btCollisionShape& shape, const btTransform& transform,
|
RecastMeshObject::RecastMeshObject(const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType)
|
const AreaType areaType)
|
||||||
: mShape(shape)
|
: mHolder(shape.getHolder())
|
||||||
|
, mShape(shape.getShape())
|
||||||
, mTransform(transform)
|
, mTransform(transform)
|
||||||
, mAreaType(areaType)
|
, mAreaType(areaType)
|
||||||
, mLocalScaling(shape.getLocalScaling())
|
, mLocalScaling(mShape.get().getLocalScaling())
|
||||||
, mChildren(makeChildrenObjects(shape, mAreaType))
|
, mChildren(makeChildrenObjects(mHolder, mShape.get(), mAreaType))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,20 +78,4 @@ namespace DetourNavigator
|
||||||
|| result;
|
|| result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RecastMeshObject> makeChildrenObjects(const btCollisionShape& shape, const AreaType areaType)
|
|
||||||
{
|
|
||||||
if (shape.isCompound())
|
|
||||||
return makeChildrenObjects(static_cast<const btCompoundShape&>(shape), areaType);
|
|
||||||
else
|
|
||||||
return std::vector<RecastMeshObject>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RecastMeshObject> makeChildrenObjects(const btCompoundShape& shape, const AreaType areaType)
|
|
||||||
{
|
|
||||||
std::vector<RecastMeshObject> result;
|
|
||||||
for (int i = 0, num = shape.getNumChildShapes(); i < num; ++i)
|
|
||||||
result.emplace_back(*shape.getChildShape(i), shape.getChildTransform(i), areaType);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
|
|
||||||
#include <LinearMath/btTransform.h>
|
#include <LinearMath/btTransform.h>
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <osg/Object>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -13,10 +16,26 @@ class btCompoundShape;
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
|
class CollisionShape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CollisionShape(osg::ref_ptr<const osg::Object> holder, const btCollisionShape& shape)
|
||||||
|
: mHolder(std::move(holder))
|
||||||
|
, mShape(shape)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const osg::ref_ptr<const osg::Object>& getHolder() const { return mHolder; }
|
||||||
|
const btCollisionShape& getShape() const { return mShape; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<const osg::Object> mHolder;
|
||||||
|
std::reference_wrapper<const btCollisionShape> mShape;
|
||||||
|
};
|
||||||
|
|
||||||
class RecastMeshObject
|
class RecastMeshObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RecastMeshObject(const btCollisionShape& shape, const btTransform& transform, const AreaType areaType);
|
RecastMeshObject(const CollisionShape& shape, const btTransform& transform, const AreaType areaType);
|
||||||
|
|
||||||
bool update(const btTransform& transform, const AreaType areaType);
|
bool update(const btTransform& transform, const AreaType areaType);
|
||||||
|
|
||||||
|
@ -36,16 +55,13 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
osg::ref_ptr<const osg::Object> mHolder;
|
||||||
std::reference_wrapper<const btCollisionShape> mShape;
|
std::reference_wrapper<const btCollisionShape> mShape;
|
||||||
btTransform mTransform;
|
btTransform mTransform;
|
||||||
AreaType mAreaType;
|
AreaType mAreaType;
|
||||||
btVector3 mLocalScaling;
|
btVector3 mLocalScaling;
|
||||||
std::vector<RecastMeshObject> mChildren;
|
std::vector<RecastMeshObject> mChildren;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<RecastMeshObject> makeChildrenObjects(const btCollisionShape& shape, const AreaType areaType);
|
|
||||||
|
|
||||||
std::vector<RecastMeshObject> makeChildrenObjects(const btCompoundShape& shape, const AreaType areaType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,14 +12,14 @@ namespace DetourNavigator
|
||||||
: mSettings(settings)
|
: mSettings(settings)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool TileCachedRecastMeshManager::addObject(const ObjectId id, const btCollisionShape& shape,
|
bool TileCachedRecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape,
|
||||||
const btTransform& transform, const AreaType areaType)
|
const btTransform& transform, const AreaType areaType)
|
||||||
{
|
{
|
||||||
std::vector<TilePosition> tilesPositions;
|
std::vector<TilePosition> tilesPositions;
|
||||||
const auto border = getBorderSize(mSettings);
|
const auto border = getBorderSize(mSettings);
|
||||||
{
|
{
|
||||||
auto tiles = mTiles.lock();
|
auto tiles = mTiles.lock();
|
||||||
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& tilePosition)
|
getTilesPositions(shape.getShape(), transform, mSettings, [&] (const TilePosition& tilePosition)
|
||||||
{
|
{
|
||||||
if (addTile(id, shape, transform, areaType, tilePosition, border, tiles.get()))
|
if (addTile(id, shape, transform, areaType, tilePosition, border, tiles.get()))
|
||||||
tilesPositions.push_back(tilePosition);
|
tilesPositions.push_back(tilePosition);
|
||||||
|
@ -156,7 +156,7 @@ namespace DetourNavigator
|
||||||
it->second.reportNavMeshChange(recastMeshVersion, navMeshVersion);
|
it->second.reportNavMeshChange(recastMeshVersion, navMeshVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TileCachedRecastMeshManager::addTile(const ObjectId id, const btCollisionShape& shape,
|
bool TileCachedRecastMeshManager::addTile(const ObjectId id, const CollisionShape& shape,
|
||||||
const btTransform& transform, const AreaType areaType, const TilePosition& tilePosition, float border,
|
const btTransform& transform, const AreaType areaType, const TilePosition& tilePosition, float border,
|
||||||
std::map<TilePosition, CachedRecastMeshManager>& tiles)
|
std::map<TilePosition, CachedRecastMeshManager>& tiles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,11 +21,11 @@ namespace DetourNavigator
|
||||||
public:
|
public:
|
||||||
TileCachedRecastMeshManager(const Settings& settings);
|
TileCachedRecastMeshManager(const Settings& settings);
|
||||||
|
|
||||||
bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType);
|
const AreaType areaType);
|
||||||
|
|
||||||
template <class OnChangedTile>
|
template <class OnChangedTile>
|
||||||
bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool updateObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType, OnChangedTile&& onChangedTile)
|
const AreaType areaType, OnChangedTile&& onChangedTile)
|
||||||
{
|
{
|
||||||
const auto object = mObjectsTilesPositions.find(id);
|
const auto object = mObjectsTilesPositions.find(id);
|
||||||
|
@ -55,7 +55,7 @@ namespace DetourNavigator
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getTilesPositions(shape, transform, mSettings, onTilePosition);
|
getTilesPositions(shape.getShape(), transform, mSettings, onTilePosition);
|
||||||
std::sort(newTiles.begin(), newTiles.end());
|
std::sort(newTiles.begin(), newTiles.end());
|
||||||
for (const auto& tile : currentTiles)
|
for (const auto& tile : currentTiles)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,7 @@ namespace DetourNavigator
|
||||||
std::size_t mRevision = 0;
|
std::size_t mRevision = 0;
|
||||||
std::size_t mTilesGeneration = 0;
|
std::size_t mTilesGeneration = 0;
|
||||||
|
|
||||||
bool addTile(const ObjectId id, const btCollisionShape& shape, const btTransform& transform,
|
bool addTile(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||||
const AreaType areaType, const TilePosition& tilePosition, float border,
|
const AreaType areaType, const TilePosition& tilePosition, float border,
|
||||||
std::map<TilePosition, CachedRecastMeshManager>& tiles);
|
std::map<TilePosition, CachedRecastMeshManager>& tiles);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
#include <BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h>
|
#include <BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h>
|
||||||
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
||||||
|
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
|
@ -75,6 +76,9 @@ btCollisionShape* BulletShape::duplicateCollisionShape(const btCollisionShape *s
|
||||||
return new btBoxShape(*boxshape);
|
return new btBoxShape(*boxshape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE)
|
||||||
|
return new btHeightfieldTerrainShape(static_cast<const btHeightfieldTerrainShape&>(*shape));
|
||||||
|
|
||||||
throw std::logic_error(std::string("Unhandled Bullet shape duplication: ")+shape->getName());
|
throw std::logic_error(std::string("Unhandled Bullet shape duplication: ")+shape->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue