mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 07:15:34 +00:00
Store mesh source data in recast mesh
This commit is contained in:
parent
0603aa131d
commit
5a6b39f8e0
23 changed files with 236 additions and 108 deletions
|
@ -145,7 +145,7 @@ namespace
|
|||
std::vector<CellWater> water;
|
||||
generateWater(std::back_inserter(water), 1, random);
|
||||
RecastMesh recastMesh(generation, revision, std::move(mesh), std::move(water),
|
||||
{generateHeightfield(random)}, {generateFlatHeightfield(random)});
|
||||
{generateHeightfield(random)}, {generateFlatHeightfield(random)}, {});
|
||||
return Key {agentHalfExtents, tilePosition, std::move(recastMesh)};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MWPhysics
|
|||
mPtr = updated;
|
||||
}
|
||||
|
||||
MWWorld::Ptr getPtr()
|
||||
MWWorld::Ptr getPtr() const
|
||||
{
|
||||
return mPtr;
|
||||
}
|
||||
|
|
|
@ -64,14 +64,23 @@ namespace
|
|||
* osg::Quat(zr, osg::Vec3(0, 0, -1));
|
||||
}
|
||||
|
||||
osg::Quat makeNodeRotation(const MWWorld::Ptr& ptr, RotationOrder order)
|
||||
osg::Quat makeInverseNodeRotation(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
const auto pos = ptr.getRefData().getPosition();
|
||||
return ptr.getClass().isActor() ? makeActorOsgQuat(pos) : makeInversedOrderObjectOsgQuat(pos);
|
||||
}
|
||||
|
||||
const auto rot = ptr.getClass().isActor() ? makeActorOsgQuat(pos)
|
||||
: (order == RotationOrder::inverse ? makeInversedOrderObjectOsgQuat(pos) : Misc::Convert::makeOsgQuat(pos));
|
||||
osg::Quat makeDirectNodeRotation(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
const auto pos = ptr.getRefData().getPosition();
|
||||
return ptr.getClass().isActor() ? makeActorOsgQuat(pos) : Misc::Convert::makeOsgQuat(pos);
|
||||
}
|
||||
|
||||
return rot;
|
||||
osg::Quat makeNodeRotation(const MWWorld::Ptr& ptr, RotationOrder order)
|
||||
{
|
||||
if (order == RotationOrder::inverse)
|
||||
return makeInverseNodeRotation(ptr);
|
||||
return makeDirectNodeRotation(ptr);
|
||||
}
|
||||
|
||||
void setNodeRotation(const MWWorld::Ptr& ptr, MWRender::RenderingManager& rendering, const osg::Quat &rotation)
|
||||
|
@ -101,7 +110,7 @@ namespace
|
|||
}
|
||||
|
||||
std::string model = getModel(ptr, rendering.getResourceSystem()->getVFS());
|
||||
const auto rotation = makeNodeRotation(ptr, RotationOrder::direct);
|
||||
const auto rotation = makeDirectNodeRotation(ptr);
|
||||
|
||||
const ESM::RefNum& refnum = ptr.getCellRef().getRefNum();
|
||||
if (!refnum.hasContentFile() || pagedRefs.find(refnum) == pagedRefs.end())
|
||||
|
@ -128,6 +137,8 @@ namespace
|
|||
{
|
||||
if (const auto object = physics.getObject(ptr))
|
||||
{
|
||||
const DetourNavigator::ObjectTransform objectTransform {ptr.getRefData().getPosition(), ptr.getCellRef().getScale()};
|
||||
|
||||
if (ptr.getClass().isDoor() && !ptr.getCellRef().getTeleport())
|
||||
{
|
||||
btVector3 aabbMin;
|
||||
|
@ -159,7 +170,7 @@ namespace
|
|||
|
||||
navigator.addObject(
|
||||
DetourNavigator::ObjectId(object),
|
||||
DetourNavigator::DoorShapes(object->getShapeInstance(), connectionStart, connectionEnd),
|
||||
DetourNavigator::DoorShapes(object->getShapeInstance(), objectTransform, connectionStart, connectionEnd),
|
||||
transform
|
||||
);
|
||||
}
|
||||
|
@ -167,7 +178,7 @@ namespace
|
|||
{
|
||||
navigator.addObject(
|
||||
DetourNavigator::ObjectId(object),
|
||||
DetourNavigator::ObjectShapes(object->getShapeInstance()),
|
||||
DetourNavigator::ObjectShapes(object->getShapeInstance(), objectTransform),
|
||||
object->getTransform()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1533,7 +1533,9 @@ namespace MWWorld
|
|||
|
||||
void World::updateNavigatorObject(const MWPhysics::Object& object)
|
||||
{
|
||||
const DetourNavigator::ObjectShapes shapes(object.getShapeInstance());
|
||||
const MWWorld::Ptr ptr = object.getPtr();
|
||||
const DetourNavigator::ObjectShapes shapes(object.getShapeInstance(),
|
||||
DetourNavigator::ObjectTransform {ptr.getRefData().getPosition(), ptr.getCellRef().getScale()});
|
||||
mShouldUpdateNavigator = mNavigator->updateObject(DetourNavigator::ObjectId(&object), shapes, object.getTransform())
|
||||
|| mShouldUpdateNavigator;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace
|
|||
const int mHeightfieldTileSize = ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1);
|
||||
const float mEndTolerance = 0;
|
||||
const btTransform mTransform {btMatrix3x3::getIdentity(), btVector3(256, 256, 0)};
|
||||
const ObjectTransform mObjectTransform {ESM::Position {{256, 256, 0}, {0, 0, 0}}, 0.0f};
|
||||
|
||||
DetourNavigatorNavigatorTest()
|
||||
: mPlayerPosition(256, 256, 0)
|
||||
|
@ -258,7 +259,7 @@ namespace
|
|||
Vec3fEq(460, 56.66666412353515625, 1.99998295307159423828125)
|
||||
)) << mPath;
|
||||
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -311,7 +312,7 @@ namespace
|
|||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -346,7 +347,7 @@ namespace
|
|||
|
||||
compound.shape().updateChildTransform(0, btTransform(btMatrix3x3::getIdentity(), btVector3(1000, 0, 0)));
|
||||
|
||||
mNavigator->updateObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), mTransform);
|
||||
mNavigator->updateObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -404,8 +405,8 @@ namespace
|
|||
heightfield2.shape().setLocalScaling(btVector3(128, 128, 1));
|
||||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addObject(ObjectId(&heightfield1.shape()), ObjectShapes(heightfield1.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&heightfield2.shape()), ObjectShapes(heightfield2.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&heightfield1.shape()), ObjectShapes(heightfield1.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->addObject(ObjectId(&heightfield2.shape()), ObjectShapes(heightfield2.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -494,7 +495,7 @@ namespace
|
|||
osg::ref_ptr<const Resource::BulletShapeInstance> instance(new Resource::BulletShapeInstance(bulletShape));
|
||||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addObject(ObjectId(instance->mCollisionShape.get()), ObjectShapes(instance), mTransform);
|
||||
mNavigator->addObject(ObjectId(instance->mCollisionShape.get()), ObjectShapes(instance, mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -725,7 +726,7 @@ namespace
|
|||
heightfield.shape().setLocalScaling(btVector3(128, 128, 1));
|
||||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addObject(ObjectId(&heightfield.shape()), ObjectShapes(heightfield.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&heightfield.shape()), ObjectShapes(heightfield.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -733,7 +734,7 @@ namespace
|
|||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
mNavigator->addObject(ObjectId(&heightfield.shape()), ObjectShapes(heightfield.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&heightfield.shape()), ObjectShapes(heightfield.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -876,7 +877,7 @@ namespace
|
|||
for (std::size_t i = 0; i < boxes.size(); ++i)
|
||||
{
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(shift.x() + i * 10, shift.y() + i * 10, i * 10));
|
||||
mNavigator->addObject(ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance()), transform);
|
||||
mNavigator->addObject(ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance(), mObjectTransform), transform);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
|
@ -884,7 +885,7 @@ namespace
|
|||
for (std::size_t i = 0; i < boxes.size(); ++i)
|
||||
{
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(shift.x() + i * 10 + 1, shift.y() + i * 10 + 1, i * 10 + 1));
|
||||
mNavigator->updateObject(ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance()), transform);
|
||||
mNavigator->updateObject(ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance(), mObjectTransform), transform);
|
||||
}
|
||||
|
||||
mNavigator->update(mPlayerPosition);
|
||||
|
@ -930,7 +931,7 @@ namespace
|
|||
for (std::size_t i = 0; i < shapes.size(); ++i)
|
||||
{
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32, i * 32, i * 32));
|
||||
mNavigator->addObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance()), transform);
|
||||
mNavigator->addObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform);
|
||||
}
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
@ -939,7 +940,7 @@ namespace
|
|||
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));
|
||||
mNavigator->updateObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance()), transform);
|
||||
mNavigator->updateObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform);
|
||||
}
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
@ -947,7 +948,7 @@ namespace
|
|||
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));
|
||||
mNavigator->updateObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance()), transform);
|
||||
mNavigator->updateObject(ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform);
|
||||
}
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
@ -1001,10 +1002,10 @@ namespace
|
|||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface);
|
||||
mNavigator->addObject(ObjectId(&oscillatingBox.shape()), ObjectShapes(oscillatingBox.instance()),
|
||||
mNavigator->addObject(ObjectId(&oscillatingBox.shape()), ObjectShapes(oscillatingBox.instance(), mObjectTransform),
|
||||
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition));
|
||||
// add this box to make navmesh bound box independent from oscillatingBoxShape rotations
|
||||
mNavigator->addObject(ObjectId(&borderBox.shape()), ObjectShapes(borderBox.instance()),
|
||||
mNavigator->addObject(ObjectId(&borderBox.shape()), ObjectShapes(borderBox.instance(), mObjectTransform),
|
||||
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition + btVector3(0, 0, 200)));
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
@ -1019,7 +1020,7 @@ namespace
|
|||
{
|
||||
const btTransform transform(btQuaternion(btVector3(0, 0, 1), n * 2 * osg::PI / 10),
|
||||
oscillatingBoxShapePosition);
|
||||
mNavigator->updateObject(ObjectId(&oscillatingBox.shape()), ObjectShapes(oscillatingBox.instance()), transform);
|
||||
mNavigator->updateObject(ObjectId(&oscillatingBox.shape()), ObjectShapes(oscillatingBox.instance(), mObjectTransform), transform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
}
|
||||
|
@ -1085,7 +1086,7 @@ namespace
|
|||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
@ -1124,7 +1125,7 @@ namespace
|
|||
|
||||
mNavigator->addAgent(mAgentHalfExtents);
|
||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance()), mTransform);
|
||||
mNavigator->addObject(ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform);
|
||||
mNavigator->update(mPlayerPosition);
|
||||
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
|
||||
|
||||
|
|
|
@ -147,7 +147,8 @@ namespace
|
|||
const std::vector<CellWater> mWater {};
|
||||
const std::vector<Heightfield> mHeightfields {};
|
||||
const std::vector<FlatHeightfield> mFlatHeightfields {};
|
||||
const RecastMesh mRecastMesh {mGeneration, mRevision, mMesh, mWater, mHeightfields, mFlatHeightfields};
|
||||
const std::vector<MeshSource> mSources {};
|
||||
const RecastMesh mRecastMesh {mGeneration, mRevision, mMesh, mWater, mHeightfields, mFlatHeightfields, mSources};
|
||||
std::unique_ptr<PreparedNavMeshData> mPreparedNavMeshData {makePeparedNavMeshData(3)};
|
||||
|
||||
const std::size_t mRecastMeshSize = sizeof(mRecastMesh) + getSize(mRecastMesh);
|
||||
|
@ -235,7 +236,7 @@ namespace
|
|||
const std::size_t maxSize = 1;
|
||||
NavMeshTilesCache cache(maxSize);
|
||||
const std::vector<CellWater> water(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh unexistentRecastMesh {mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh unexistentRecastMesh(mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields, mSources);
|
||||
|
||||
cache.set(mAgentHalfExtents, mTilePosition, mRecastMesh, std::move(mPreparedNavMeshData));
|
||||
EXPECT_FALSE(cache.get(mAgentHalfExtents, mTilePosition, unexistentRecastMesh));
|
||||
|
@ -247,7 +248,7 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> water(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh anotherRecastMesh {mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh anotherRecastMesh(mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields, mSources);
|
||||
auto anotherPreparedNavMeshData = makePeparedNavMeshData(3);
|
||||
const auto copy = clone(*anotherPreparedNavMeshData);
|
||||
|
||||
|
@ -265,7 +266,7 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> water(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh anotherRecastMesh {mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh anotherRecastMesh(mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields, mSources);
|
||||
auto anotherPreparedNavMeshData = makePeparedNavMeshData(3);
|
||||
|
||||
const auto value = cache.set(mAgentHalfExtents, mTilePosition, mRecastMesh,
|
||||
|
@ -281,13 +282,13 @@ namespace
|
|||
const auto copy = clone(*mPreparedNavMeshData);
|
||||
|
||||
const std::vector<CellWater> leastRecentlySetWater(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh leastRecentlySetRecastMesh {mGeneration, mRevision, mMesh, leastRecentlySetWater,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh leastRecentlySetRecastMesh(mGeneration, mRevision, mMesh, leastRecentlySetWater,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto leastRecentlySetData = makePeparedNavMeshData(3);
|
||||
|
||||
const std::vector<CellWater> mostRecentlySetWater(1, CellWater {osg::Vec2i(), Water {2, 0.0f}});
|
||||
const RecastMesh mostRecentlySetRecastMesh {mGeneration, mRevision, mMesh, mostRecentlySetWater,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh mostRecentlySetRecastMesh(mGeneration, mRevision, mMesh, mostRecentlySetWater,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto mostRecentlySetData = makePeparedNavMeshData(3);
|
||||
|
||||
ASSERT_TRUE(cache.set(mAgentHalfExtents, mTilePosition, leastRecentlySetRecastMesh,
|
||||
|
@ -309,14 +310,14 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> leastRecentlyUsedWater(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh leastRecentlyUsedRecastMesh {mGeneration, mRevision, mMesh, leastRecentlyUsedWater,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh leastRecentlyUsedRecastMesh(mGeneration, mRevision, mMesh, leastRecentlyUsedWater,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto leastRecentlyUsedData = makePeparedNavMeshData(3);
|
||||
const auto leastRecentlyUsedCopy = clone(*leastRecentlyUsedData);
|
||||
|
||||
const std::vector<CellWater> mostRecentlyUsedWater(1, CellWater {osg::Vec2i(), Water {2, 0.0f}});
|
||||
const RecastMesh mostRecentlyUsedRecastMesh {mGeneration, mRevision, mMesh, mostRecentlyUsedWater,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh mostRecentlyUsedRecastMesh(mGeneration, mRevision, mMesh, mostRecentlyUsedWater,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto mostRecentlyUsedData = makePeparedNavMeshData(3);
|
||||
const auto mostRecentlyUsedCopy = clone(*mostRecentlyUsedData);
|
||||
|
||||
|
@ -350,8 +351,8 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> water(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh tooLargeRecastMesh {mGeneration, mRevision, mMesh, water,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh tooLargeRecastMesh(mGeneration, mRevision, mMesh, water,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto tooLargeData = makePeparedNavMeshData(10);
|
||||
|
||||
cache.set(mAgentHalfExtents, mTilePosition, mRecastMesh, std::move(mPreparedNavMeshData));
|
||||
|
@ -365,13 +366,13 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> anotherWater(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh anotherRecastMesh {mGeneration, mRevision, mMesh, anotherWater,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh anotherRecastMesh(mGeneration, mRevision, mMesh, anotherWater,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto anotherData = makePeparedNavMeshData(3);
|
||||
|
||||
const std::vector<CellWater> tooLargeWater(1, CellWater {osg::Vec2i(), Water {2, 0.0f}});
|
||||
const RecastMesh tooLargeRecastMesh {mGeneration, mRevision, mMesh, tooLargeWater,
|
||||
mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh tooLargeRecastMesh(mGeneration, mRevision, mMesh, tooLargeWater,
|
||||
mHeightfields, mFlatHeightfields, mSources);
|
||||
auto tooLargeData = makePeparedNavMeshData(10);
|
||||
|
||||
const auto value = cache.set(mAgentHalfExtents, mTilePosition, mRecastMesh,
|
||||
|
@ -391,7 +392,7 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> water(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh anotherRecastMesh {mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh anotherRecastMesh(mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields, mSources);
|
||||
auto anotherData = makePeparedNavMeshData(3);
|
||||
|
||||
const auto firstCopy = cache.set(mAgentHalfExtents, mTilePosition, mRecastMesh, std::move(mPreparedNavMeshData));
|
||||
|
@ -410,7 +411,7 @@ namespace
|
|||
NavMeshTilesCache cache(maxSize);
|
||||
|
||||
const std::vector<CellWater> water(1, CellWater {osg::Vec2i(), Water {1, 0.0f}});
|
||||
const RecastMesh anotherRecastMesh {mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields};
|
||||
const RecastMesh anotherRecastMesh(mGeneration, mRevision, mMesh, water, mHeightfields, mFlatHeightfields, mSources);
|
||||
auto anotherData = makePeparedNavMeshData(3);
|
||||
|
||||
cache.set(mAgentHalfExtents, mTilePosition, mRecastMesh, std::move(mPreparedNavMeshData));
|
||||
|
|
|
@ -89,6 +89,8 @@ namespace
|
|||
TileBounds mBounds;
|
||||
const std::size_t mGeneration = 0;
|
||||
const std::size_t mRevision = 0;
|
||||
const osg::ref_ptr<const Resource::BulletShape> mSource {nullptr};
|
||||
const ObjectTransform mObjectTransform {ESM::Position {{0, 0, 0}, {0, 0, 0}}, 0.0f};
|
||||
|
||||
DetourNavigatorRecastMeshBuilderTest()
|
||||
{
|
||||
|
@ -115,7 +117,8 @@ namespace
|
|||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(),
|
||||
AreaType_ground, mSource, mObjectTransform);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, -1, 0,
|
||||
|
@ -135,7 +138,7 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -152,7 +155,8 @@ namespace
|
|||
const std::array<btScalar, 4> heightfieldData {{0, 0, 0, 0}};
|
||||
btHeightfieldTerrainShape shape(2, 2, heightfieldData.data(), 1, 0, 0, 2, PHY_FLOAT, false);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(),
|
||||
AreaType_ground, mSource, mObjectTransform);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-0.5, -0.5, 0,
|
||||
|
@ -168,7 +172,8 @@ namespace
|
|||
{
|
||||
btBoxShape shape(btVector3(1, 1, 2));
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(),
|
||||
AreaType_ground, mSource, mObjectTransform);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, -1, -2,
|
||||
|
@ -214,7 +219,7 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform::getIdentity(),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -261,7 +266,7 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -285,7 +290,7 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -307,7 +312,7 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform::getIdentity(),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -334,7 +339,7 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform::getIdentity(),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -359,7 +364,7 @@ namespace
|
|||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btQuaternion(btVector3(1, 0, 0),
|
||||
static_cast<btScalar>(-osg::PI_4))),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||
|
@ -384,7 +389,7 @@ namespace
|
|||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btQuaternion(btVector3(0, 1, 0),
|
||||
static_cast<btScalar>(osg::PI_4))),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||
|
@ -409,7 +414,7 @@ namespace
|
|||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btQuaternion(btVector3(0, 0, 1),
|
||||
static_cast<btScalar>(osg::PI_4))),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||
|
@ -433,12 +438,12 @@ namespace
|
|||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape1),
|
||||
btTransform::getIdentity(),
|
||||
AreaType_ground
|
||||
AreaType_ground, mSource, mObjectTransform
|
||||
);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape2),
|
||||
btTransform::getIdentity(),
|
||||
AreaType_null
|
||||
AreaType_null, mSource, mObjectTransform
|
||||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
|
@ -471,7 +476,7 @@ namespace
|
|||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground, mSource, mObjectTransform);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, -1, 0,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "operators.hpp"
|
||||
|
||||
#include <components/detournavigator/recastmeshobject.hpp>
|
||||
#include <components/misc/convert.hpp>
|
||||
|
||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
||||
|
@ -15,10 +16,11 @@ namespace
|
|||
struct DetourNavigatorRecastMeshObjectTest : Test
|
||||
{
|
||||
btBoxShape mBoxShapeImpl {btVector3(1, 2, 3)};
|
||||
CollisionShape mBoxShape {nullptr, mBoxShapeImpl};
|
||||
const ObjectTransform mObjectTransform {ESM::Position {{1, 2, 3}, {1, 2, 3}}, 0.5f};
|
||||
CollisionShape mBoxShape {nullptr, mBoxShapeImpl, mObjectTransform};
|
||||
btCompoundShape mCompoundShapeImpl {true};
|
||||
CollisionShape mCompoundShape {nullptr, mCompoundShapeImpl};
|
||||
btTransform mTransform {btQuaternion(btVector3(1, 2, 3), 1), btVector3(1, 2, 3)};
|
||||
CollisionShape mCompoundShape {nullptr, mCompoundShapeImpl, mObjectTransform};
|
||||
btTransform mTransform {Misc::Convert::makeBulletTransform(mObjectTransform.mPosition)};
|
||||
|
||||
DetourNavigatorRecastMeshObjectTest()
|
||||
{
|
||||
|
|
|
@ -17,6 +17,9 @@ namespace
|
|||
{
|
||||
Settings mSettings;
|
||||
std::vector<TilePosition> mChangedTiles;
|
||||
const ObjectTransform mObjectTransform {ESM::Position {{0, 0, 0}, {0, 0, 0}}, 0.0f};
|
||||
const osg::ref_ptr<const Resource::BulletShape> mShape = new Resource::BulletShape;
|
||||
const osg::ref_ptr<const Resource::BulletShapeInstance> mInstance = new Resource::BulletShapeInstance(mShape);
|
||||
|
||||
DetourNavigatorTileCachedRecastMeshManagerTest()
|
||||
{
|
||||
|
@ -56,7 +59,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
EXPECT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||
}
|
||||
|
||||
|
@ -64,7 +67,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
EXPECT_FALSE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||
}
|
||||
|
@ -73,7 +76,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||
for (int x = -1; x < 1; ++x)
|
||||
for (int y = -1; y < 1; ++y)
|
||||
|
@ -85,7 +88,7 @@ namespace
|
|||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
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); }));
|
||||
|
@ -100,7 +103,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
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); }));
|
||||
|
@ -111,7 +114,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||
EXPECT_NE(manager.getMesh(TilePosition(-1, 0)), nullptr);
|
||||
|
@ -123,7 +126,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
EXPECT_EQ(manager.getMesh(TilePosition(1, 0)), nullptr);
|
||||
}
|
||||
|
@ -133,7 +136,7 @@ namespace
|
|||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
|
||||
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||
EXPECT_NE(manager.getMesh(TilePosition(0, -1)), nullptr);
|
||||
|
@ -153,7 +156,7 @@ namespace
|
|||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
|
||||
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||
EXPECT_EQ(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||
|
@ -168,7 +171,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
manager.removeObject(ObjectId(&boxShape));
|
||||
EXPECT_EQ(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||
|
@ -181,7 +184,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
EXPECT_NE(manager.getMesh(TilePosition(-1, -1)), nullptr);
|
||||
|
@ -201,7 +204,7 @@ namespace
|
|||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const auto initialRevision = manager.getRevision();
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
EXPECT_EQ(manager.getRevision(), initialRevision + 1);
|
||||
}
|
||||
|
@ -210,7 +213,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
const auto beforeAddRevision = manager.getRevision();
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
|
@ -222,7 +225,7 @@ namespace
|
|||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(getTileSize(mSettings) / mSettings.mRecastScaleFactor, 0, 0));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground);
|
||||
const auto beforeUpdateRevision = manager.getRevision();
|
||||
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||
|
@ -233,7 +236,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
const auto beforeUpdateRevision = manager.getRevision();
|
||||
manager.updateObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, [] (auto) {});
|
||||
|
@ -244,7 +247,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
|
||||
const auto beforeRemoveRevision = manager.getRevision();
|
||||
manager.removeObject(ObjectId(&boxShape));
|
||||
|
@ -282,7 +285,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||
const osg::Vec2i cellPosition(0, 0);
|
||||
const int cellSize = std::numeric_limits<int>::max();
|
||||
|
@ -325,7 +328,7 @@ namespace
|
|||
{
|
||||
TileCachedRecastMeshManager manager(mSettings);
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||
const osg::Vec2i cellPosition(0, 0);
|
||||
const int cellSize = 8192;
|
||||
|
@ -342,7 +345,7 @@ namespace
|
|||
const osg::Vec2i cellPosition(0, 0);
|
||||
const int cellSize = 8192;
|
||||
const btBoxShape boxShape(btVector3(20, 20, 100));
|
||||
const CollisionShape shape(nullptr, boxShape);
|
||||
const CollisionShape shape(mInstance, boxShape, mObjectTransform);
|
||||
ASSERT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
|
||||
ASSERT_TRUE(manager.addWater(cellPosition, cellSize, 0.0f));
|
||||
ASSERT_TRUE(manager.removeObject(ObjectId(&boxShape)));
|
||||
|
|
|
@ -203,6 +203,7 @@ add_component_dir(detournavigator
|
|||
preparednavmeshdata
|
||||
navmeshcacheitem
|
||||
navigatorutils
|
||||
generatenavmeshtile
|
||||
)
|
||||
|
||||
add_component_dir(loadinglistener
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <Recast.h>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
enum AreaType : unsigned char
|
||||
|
@ -21,6 +23,19 @@ namespace DetourNavigator
|
|||
float mPathgrid = 1.0f;
|
||||
float mGround = 1.0f;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream, AreaType value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case AreaType_null: return stream << "null";
|
||||
case AreaType_water: return stream << "water";
|
||||
case AreaType_door: return stream << "door";
|
||||
case AreaType_pathgrid: return stream << "pathgrid";
|
||||
case AreaType_ground: return stream << "ground";
|
||||
}
|
||||
return stream << "unknown area type (" << static_cast<std::underlying_type_t<AreaType>>(value) << ")";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "recastmeshtiles.hpp"
|
||||
#include "waitconditiontype.hpp"
|
||||
#include "heightfieldshape.hpp"
|
||||
#include "objecttransform.hpp"
|
||||
|
||||
#include <components/resource/bulletshape.hpp>
|
||||
|
||||
|
@ -27,10 +28,14 @@ namespace DetourNavigator
|
|||
struct ObjectShapes
|
||||
{
|
||||
osg::ref_ptr<const Resource::BulletShapeInstance> mShapeInstance;
|
||||
ObjectTransform mTransform;
|
||||
|
||||
ObjectShapes(const osg::ref_ptr<const Resource::BulletShapeInstance>& shapeInstance)
|
||||
ObjectShapes(const osg::ref_ptr<const Resource::BulletShapeInstance>& shapeInstance, const ObjectTransform& transform)
|
||||
: mShapeInstance(shapeInstance)
|
||||
{}
|
||||
, mTransform(transform)
|
||||
{
|
||||
assert(mShapeInstance != nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
struct DoorShapes : ObjectShapes
|
||||
|
@ -39,8 +44,8 @@ namespace DetourNavigator
|
|||
osg::Vec3f mConnectionEnd;
|
||||
|
||||
DoorShapes(const osg::ref_ptr<const Resource::BulletShapeInstance>& shapeInstance,
|
||||
const osg::Vec3f& connectionStart,const osg::Vec3f& connectionEnd)
|
||||
: ObjectShapes(shapeInstance)
|
||||
const ObjectTransform& transform, const osg::Vec3f& connectionStart, const osg::Vec3f& connectionEnd)
|
||||
: ObjectShapes(shapeInstance, transform)
|
||||
, mConnectionStart(connectionStart)
|
||||
, mConnectionEnd(connectionEnd)
|
||||
{}
|
||||
|
|
|
@ -34,12 +34,12 @@ namespace DetourNavigator
|
|||
|
||||
bool NavigatorImpl::addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform)
|
||||
{
|
||||
CollisionShape collisionShape {shapes.mShapeInstance, *shapes.mShapeInstance->mCollisionShape};
|
||||
const CollisionShape collisionShape(shapes.mShapeInstance, *shapes.mShapeInstance->mCollisionShape, shapes.mTransform);
|
||||
bool result = mNavMeshManager.addObject(id, collisionShape, transform, AreaType_ground);
|
||||
if (const btCollisionShape* const avoidShape = shapes.mShapeInstance->mAvoidCollisionShape.get())
|
||||
{
|
||||
const ObjectId avoidId(avoidShape);
|
||||
CollisionShape avoidCollisionShape {shapes.mShapeInstance, *avoidShape};
|
||||
const CollisionShape avoidCollisionShape(shapes.mShapeInstance, *avoidShape, shapes.mTransform);
|
||||
if (mNavMeshManager.addObject(avoidId, avoidCollisionShape, transform, AreaType_null))
|
||||
{
|
||||
updateAvoidShapeId(id, avoidId);
|
||||
|
@ -64,12 +64,12 @@ namespace DetourNavigator
|
|||
|
||||
bool NavigatorImpl::updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform)
|
||||
{
|
||||
const CollisionShape collisionShape {shapes.mShapeInstance, *shapes.mShapeInstance->mCollisionShape};
|
||||
const CollisionShape collisionShape(shapes.mShapeInstance, *shapes.mShapeInstance->mCollisionShape, shapes.mTransform);
|
||||
bool result = mNavMeshManager.updateObject(id, collisionShape, transform, AreaType_ground);
|
||||
if (const btCollisionShape* const avoidShape = shapes.mShapeInstance->mAvoidCollisionShape.get())
|
||||
{
|
||||
const ObjectId avoidId(avoidShape);
|
||||
const CollisionShape avoidCollisionShape {shapes.mShapeInstance, *avoidShape};
|
||||
const CollisionShape avoidCollisionShape(shapes.mShapeInstance, *avoidShape, shapes.mTransform);
|
||||
if (mNavMeshManager.updateObject(avoidId, avoidCollisionShape, transform, AreaType_null))
|
||||
{
|
||||
updateAvoidShapeId(id, avoidId);
|
||||
|
|
27
components/detournavigator/objecttransform.hpp
Normal file
27
components/detournavigator/objecttransform.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_OBJECTTRANSFORM_H
|
||||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_OBJECTTRANSFORM_H
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct ObjectTransform
|
||||
{
|
||||
ESM::Position mPosition;
|
||||
float mScale;
|
||||
|
||||
friend inline auto tie(const ObjectTransform& v)
|
||||
{
|
||||
return std::tie(v.mPosition, v.mScale);
|
||||
}
|
||||
|
||||
friend inline bool operator<(const ObjectTransform& l, const ObjectTransform& r)
|
||||
{
|
||||
return tie(l) < tie(r);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,13 +19,15 @@ namespace DetourNavigator
|
|||
}
|
||||
|
||||
RecastMesh::RecastMesh(std::size_t generation, std::size_t revision, Mesh mesh, std::vector<CellWater> water,
|
||||
std::vector<Heightfield> heightfields, std::vector<FlatHeightfield> flatHeightfields)
|
||||
std::vector<Heightfield> heightfields, std::vector<FlatHeightfield> flatHeightfields,
|
||||
std::vector<MeshSource> meshSources)
|
||||
: mGeneration(generation)
|
||||
, mRevision(revision)
|
||||
, mMesh(std::move(mesh))
|
||||
, mWater(std::move(water))
|
||||
, mHeightfields(std::move(heightfields))
|
||||
, mFlatHeightfields(std::move(flatHeightfields))
|
||||
, mMeshSources(std::move(meshSources))
|
||||
{
|
||||
mWater.shrink_to_fit();
|
||||
mHeightfields.shrink_to_fit();
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
#include "areatype.hpp"
|
||||
#include "bounds.hpp"
|
||||
#include "tilebounds.hpp"
|
||||
#include "objecttransform.hpp"
|
||||
|
||||
#include <components/bullethelpers/operators.hpp>
|
||||
#include <components/resource/bulletshape.hpp>
|
||||
|
||||
#include <osg/Vec3f>
|
||||
#include <osg/Vec2i>
|
||||
|
@ -119,11 +121,19 @@ namespace DetourNavigator
|
|||
return tie(lhs) < tie(rhs);
|
||||
}
|
||||
|
||||
struct MeshSource
|
||||
{
|
||||
osg::ref_ptr<const Resource::BulletShape> mShape;
|
||||
ObjectTransform mObjectTransform;
|
||||
AreaType mAreaType;
|
||||
};
|
||||
|
||||
class RecastMesh
|
||||
{
|
||||
public:
|
||||
RecastMesh(std::size_t generation, std::size_t revision, Mesh mesh, std::vector<CellWater> water,
|
||||
std::vector<Heightfield> heightfields, std::vector<FlatHeightfield> flatHeightfields);
|
||||
std::vector<Heightfield> heightfields, std::vector<FlatHeightfield> flatHeightfields,
|
||||
std::vector<MeshSource> sources);
|
||||
|
||||
std::size_t getGeneration() const
|
||||
{
|
||||
|
@ -152,6 +162,8 @@ namespace DetourNavigator
|
|||
return mFlatHeightfields;
|
||||
}
|
||||
|
||||
const std::vector<MeshSource>& getMeshSources() const noexcept { return mMeshSources; }
|
||||
|
||||
private:
|
||||
std::size_t mGeneration;
|
||||
std::size_t mRevision;
|
||||
|
@ -159,6 +171,7 @@ namespace DetourNavigator
|
|||
std::vector<CellWater> mWater;
|
||||
std::vector<Heightfield> mHeightfields;
|
||||
std::vector<FlatHeightfield> mFlatHeightfields;
|
||||
std::vector<MeshSource> mMeshSources;
|
||||
|
||||
friend inline std::size_t getSize(const RecastMesh& value) noexcept
|
||||
{
|
||||
|
|
|
@ -133,6 +133,13 @@ namespace DetourNavigator
|
|||
{
|
||||
}
|
||||
|
||||
void RecastMeshBuilder::addObject(const btCollisionShape& shape, const btTransform& transform,
|
||||
const AreaType areaType, osg::ref_ptr<const Resource::BulletShape> source, const ObjectTransform& objectTransform)
|
||||
{
|
||||
addObject(shape, transform, areaType);
|
||||
mSources.push_back(MeshSource {std::move(source), objectTransform, areaType});
|
||||
}
|
||||
|
||||
void RecastMeshBuilder::addObject(const btCollisionShape& shape, const btTransform& transform,
|
||||
const AreaType areaType)
|
||||
{
|
||||
|
@ -261,7 +268,8 @@ namespace DetourNavigator
|
|||
std::sort(mWater.begin(), mWater.end());
|
||||
Mesh mesh = makeMesh(std::move(mTriangles));
|
||||
return std::make_shared<RecastMesh>(generation, revision, std::move(mesh), std::move(mWater),
|
||||
std::move(mHeightfields), std::move(mFlatHeightfields));
|
||||
std::move(mHeightfields), std::move(mFlatHeightfields),
|
||||
std::move(mSources));
|
||||
}
|
||||
|
||||
void RecastMeshBuilder::addObject(const btConcaveShape& shape, const btTransform& transform,
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "recastmesh.hpp"
|
||||
#include "tilebounds.hpp"
|
||||
|
||||
#include <components/resource/bulletshape.hpp>
|
||||
|
||||
#include <osg/Vec3f>
|
||||
|
||||
#include <LinearMath/btTransform.h>
|
||||
|
@ -38,7 +40,8 @@ namespace DetourNavigator
|
|||
public:
|
||||
explicit RecastMeshBuilder(const TileBounds& bounds) noexcept;
|
||||
|
||||
void addObject(const btCollisionShape& shape, const btTransform& transform, const AreaType areaType);
|
||||
void addObject(const btCollisionShape& shape, const btTransform& transform, const AreaType areaType,
|
||||
osg::ref_ptr<const Resource::BulletShape> source, const ObjectTransform& objectTransform);
|
||||
|
||||
void addObject(const btCompoundShape& shape, const btTransform& transform, const AreaType areaType);
|
||||
|
||||
|
@ -63,6 +66,9 @@ namespace DetourNavigator
|
|||
std::vector<CellWater> mWater;
|
||||
std::vector<Heightfield> mHeightfields;
|
||||
std::vector<FlatHeightfield> mFlatHeightfields;
|
||||
std::vector<MeshSource> mSources;
|
||||
|
||||
inline void addObject(const btCollisionShape& shape, const btTransform& transform, const AreaType areaType);
|
||||
|
||||
void addObject(const btConcaveShape& shape, const btTransform& transform, btTriangleCallback&& callback);
|
||||
|
||||
|
|
|
@ -122,7 +122,8 @@ namespace DetourNavigator
|
|||
{
|
||||
RecastMeshBuilder builder(mTileBounds);
|
||||
using Object = std::tuple<
|
||||
osg::ref_ptr<const osg::Referenced>,
|
||||
osg::ref_ptr<const Resource::BulletShapeInstance>,
|
||||
ObjectTransform,
|
||||
std::reference_wrapper<const btCollisionShape>,
|
||||
btTransform,
|
||||
AreaType
|
||||
|
@ -139,12 +140,13 @@ namespace DetourNavigator
|
|||
for (const auto& [k, object] : mObjects)
|
||||
{
|
||||
const RecastMeshObject& impl = object.getImpl();
|
||||
objects.emplace_back(impl.getHolder(), impl.getShape(), impl.getTransform(), impl.getAreaType());
|
||||
objects.emplace_back(impl.getInstance(), impl.getObjectTransform(), impl.getShape(),
|
||||
impl.getTransform(), impl.getAreaType());
|
||||
}
|
||||
revision = mRevision;
|
||||
}
|
||||
for (const auto& [holder, shape, transform, areaType] : objects)
|
||||
builder.addObject(shape, transform, areaType);
|
||||
for (const auto& [instance, objectTransform, shape, transform, areaType] : objects)
|
||||
builder.addObject(shape, transform, areaType, instance->getSource(), objectTransform);
|
||||
return std::move(builder).create(mGeneration, revision);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,8 @@ namespace DetourNavigator
|
|||
|
||||
RecastMeshObject::RecastMeshObject(const CollisionShape& shape, const btTransform& transform,
|
||||
const AreaType areaType)
|
||||
: mHolder(shape.getHolder())
|
||||
: mInstance(shape.getInstance())
|
||||
, mObjectTransform(shape.getObjectTransform())
|
||||
, mImpl(shape.getShape(), transform, areaType)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTMESHOBJECT_H
|
||||
|
||||
#include "areatype.hpp"
|
||||
#include "objecttransform.hpp"
|
||||
|
||||
#include <components/resource/bulletshape.hpp>
|
||||
|
||||
#include <LinearMath/btTransform.h>
|
||||
|
||||
|
@ -19,17 +22,21 @@ namespace DetourNavigator
|
|||
class CollisionShape
|
||||
{
|
||||
public:
|
||||
CollisionShape(osg::ref_ptr<const osg::Referenced> holder, const btCollisionShape& shape)
|
||||
: mHolder(std::move(holder))
|
||||
CollisionShape(osg::ref_ptr<const Resource::BulletShapeInstance> instance, const btCollisionShape& shape,
|
||||
const ObjectTransform& transform)
|
||||
: mInstance(std::move(instance))
|
||||
, mShape(shape)
|
||||
, mObjectTransform(transform)
|
||||
{}
|
||||
|
||||
const osg::ref_ptr<const osg::Referenced>& getHolder() const { return mHolder; }
|
||||
const osg::ref_ptr<const Resource::BulletShapeInstance>& getInstance() const { return mInstance; }
|
||||
const btCollisionShape& getShape() const { return mShape; }
|
||||
const ObjectTransform& getObjectTransform() const { return mObjectTransform; }
|
||||
|
||||
private:
|
||||
osg::ref_ptr<const osg::Referenced> mHolder;
|
||||
osg::ref_ptr<const Resource::BulletShapeInstance> mInstance;
|
||||
std::reference_wrapper<const btCollisionShape> mShape;
|
||||
ObjectTransform mObjectTransform;
|
||||
};
|
||||
|
||||
class ChildRecastMeshObject
|
||||
|
@ -60,7 +67,7 @@ namespace DetourNavigator
|
|||
|
||||
bool update(const btTransform& transform, const AreaType areaType) { return mImpl.update(transform, areaType); }
|
||||
|
||||
const osg::ref_ptr<const osg::Referenced>& getHolder() const { return mHolder; }
|
||||
const osg::ref_ptr<const Resource::BulletShapeInstance>& getInstance() const { return mInstance; }
|
||||
|
||||
const btCollisionShape& getShape() const { return mImpl.getShape(); }
|
||||
|
||||
|
@ -68,8 +75,11 @@ namespace DetourNavigator
|
|||
|
||||
AreaType getAreaType() const { return mImpl.getAreaType(); }
|
||||
|
||||
const ObjectTransform& getObjectTransform() const { return mObjectTransform; }
|
||||
|
||||
private:
|
||||
osg::ref_ptr<const osg::Referenced> mHolder;
|
||||
osg::ref_ptr<const Resource::BulletShapeInstance> mInstance;
|
||||
ObjectTransform mObjectTransform;
|
||||
ChildRecastMeshObject mImpl;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <osg/Vec3f>
|
||||
|
||||
namespace ESM
|
||||
|
@ -59,6 +61,12 @@ struct Position
|
|||
{
|
||||
return osg::Vec3f(rot[0], rot[1], rot[2]);
|
||||
}
|
||||
|
||||
friend inline bool operator<(const Position& l, const Position& r)
|
||||
{
|
||||
const auto tuple = [] (const Position& v) { return std::tuple(v.asVec3(), v.asRotationVec3()); };
|
||||
return tuple(l) < tuple(r);
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -67,6 +67,11 @@ namespace Convert
|
|||
{
|
||||
return makeBulletQuaternion(position.rot);
|
||||
}
|
||||
|
||||
inline btTransform makeBulletTransform(const ESM::Position& position)
|
||||
{
|
||||
return btTransform(makeBulletQuaternion(position), toBullet(position.asVec3()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue