mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-31 15:06:39 +00:00
Make RecastMesh independent from recast scale factor
To avoid scaling until it's required by delaying coordinates conversion until navmesh generation.
This commit is contained in:
parent
af7059373c
commit
d60edb36aa
6 changed files with 153 additions and 140 deletions
|
@ -1,7 +1,6 @@
|
|||
#include "operators.hpp"
|
||||
|
||||
#include <components/detournavigator/recastmeshbuilder.hpp>
|
||||
#include <components/detournavigator/settings.hpp>
|
||||
#include <components/detournavigator/recastmesh.hpp>
|
||||
#include <components/detournavigator/exceptions.hpp>
|
||||
|
||||
|
@ -33,14 +32,12 @@ namespace
|
|||
|
||||
struct DetourNavigatorRecastMeshBuilderTest : Test
|
||||
{
|
||||
Settings mSettings;
|
||||
TileBounds mBounds;
|
||||
const std::size_t mGeneration = 0;
|
||||
const std::size_t mRevision = 0;
|
||||
|
||||
DetourNavigatorRecastMeshBuilderTest()
|
||||
{
|
||||
mSettings.mRecastScaleFactor = 1.0f;
|
||||
mBounds.mMin = osg::Vec2f(-std::numeric_limits<float>::max() * std::numeric_limits<float>::epsilon(),
|
||||
-std::numeric_limits<float>::max() * std::numeric_limits<float>::epsilon());
|
||||
mBounds.mMax = osg::Vec2f(std::numeric_limits<float>::max() * std::numeric_limits<float>::epsilon(),
|
||||
|
@ -50,7 +47,7 @@ namespace
|
|||
|
||||
TEST_F(DetourNavigatorRecastMeshBuilderTest, create_for_empty_should_return_empty)
|
||||
{
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>());
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>());
|
||||
|
@ -63,13 +60,13 @@ namespace
|
|||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, 0, -1,
|
||||
-1, 0, 1,
|
||||
1, 0, -1,
|
||||
-1, -1, 0,
|
||||
-1, 1, 0,
|
||||
1, -1, 0,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -80,7 +77,7 @@ namespace
|
|||
btTriangleMesh mesh;
|
||||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
|
@ -88,9 +85,9 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
0, 3, 0,
|
||||
0, 3, 4,
|
||||
2, 3, 0,
|
||||
0, 0, 3,
|
||||
0, 4, 3,
|
||||
2, 0, 3,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -100,15 +97,15 @@ 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(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-0.5, 0, -0.5,
|
||||
-0.5, 0, 0.5,
|
||||
0.5, 0, -0.5,
|
||||
0.5, 0, 0.5,
|
||||
}));
|
||||
-0.5, -0.5, 0,
|
||||
-0.5, 0.5, 0,
|
||||
0.5, -0.5, 0,
|
||||
0.5, 0.5, 0,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({0, 1, 2, 2, 1, 3}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground, AreaType_ground}));
|
||||
}
|
||||
|
@ -116,32 +113,32 @@ namespace
|
|||
TEST_F(DetourNavigatorRecastMeshBuilderTest, add_box_shape_should_produce_12_triangles)
|
||||
{
|
||||
btBoxShape shape(btVector3(1, 1, 2));
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, -2, -1,
|
||||
-1, -2, 1,
|
||||
-1, 2, -1,
|
||||
-1, 2, 1,
|
||||
1, -2, -1,
|
||||
1, -2, 1,
|
||||
1, 2, -1,
|
||||
1, 2, 1,
|
||||
-1, -1, -2,
|
||||
-1, -1, 2,
|
||||
-1, 1, -2,
|
||||
-1, 1, 2,
|
||||
1, -1, -2,
|
||||
1, -1, 2,
|
||||
1, 1, -2,
|
||||
1, 1, 2,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({
|
||||
0, 1, 3,
|
||||
0, 2, 6,
|
||||
0, 4, 5,
|
||||
1, 5, 7,
|
||||
2, 3, 7,
|
||||
3, 2, 0,
|
||||
4, 6, 7,
|
||||
5, 1, 0,
|
||||
6, 4, 0,
|
||||
7, 3, 1,
|
||||
7, 5, 4,
|
||||
7, 6, 2,
|
||||
0, 1, 5,
|
||||
0, 2, 3,
|
||||
0, 4, 6,
|
||||
1, 3, 7,
|
||||
2, 6, 7,
|
||||
3, 1, 0,
|
||||
4, 5, 7,
|
||||
5, 4, 0,
|
||||
6, 2, 0,
|
||||
7, 3, 2,
|
||||
7, 5, 1,
|
||||
7, 6, 4,
|
||||
})) << recastMesh->getMesh().getIndices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>(12, AreaType_ground));
|
||||
}
|
||||
|
@ -159,7 +156,7 @@ namespace
|
|||
shape.addChildShape(btTransform::getIdentity(), &triangle1);
|
||||
shape.addChildShape(btTransform::getIdentity(), &box);
|
||||
shape.addChildShape(btTransform::getIdentity(), &triangle2);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform::getIdentity(),
|
||||
|
@ -167,34 +164,34 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, -2, -1,
|
||||
-1, -2, 1,
|
||||
-1, 0, -1,
|
||||
-1, 0, 1,
|
||||
-1, 2, -1,
|
||||
-1, 2, 1,
|
||||
1, -2, -1,
|
||||
1, -2, 1,
|
||||
1, 0, -1,
|
||||
1, 0, 1,
|
||||
1, 2, -1,
|
||||
1, 2, 1,
|
||||
-1, -1, -2,
|
||||
-1, -1, 0,
|
||||
-1, -1, 2,
|
||||
-1, 1, -2,
|
||||
-1, 1, 0,
|
||||
-1, 1, 2,
|
||||
1, -1, -2,
|
||||
1, -1, 0,
|
||||
1, -1, 2,
|
||||
1, 1, -2,
|
||||
1, 1, 0,
|
||||
1, 1, 2,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({
|
||||
0, 1, 5,
|
||||
0, 4, 10,
|
||||
0, 6, 7,
|
||||
1, 7, 11,
|
||||
4, 5, 11,
|
||||
5, 4, 0,
|
||||
6, 10, 11,
|
||||
7, 1, 0,
|
||||
8, 3, 2,
|
||||
8, 3, 9,
|
||||
10, 6, 0,
|
||||
11, 5, 1,
|
||||
11, 7, 6,
|
||||
11, 10, 4,
|
||||
0, 2, 8,
|
||||
0, 3, 5,
|
||||
0, 6, 9,
|
||||
2, 5, 11,
|
||||
3, 9, 11,
|
||||
5, 2, 0,
|
||||
6, 8, 11,
|
||||
7, 4, 1,
|
||||
7, 4, 10,
|
||||
8, 6, 0,
|
||||
9, 3, 0,
|
||||
11, 5, 3,
|
||||
11, 8, 2,
|
||||
11, 9, 6,
|
||||
})) << recastMesh->getMesh().getIndices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>(14, AreaType_ground));
|
||||
}
|
||||
|
@ -206,7 +203,7 @@ namespace
|
|||
btBvhTriangleMeshShape triangle(&mesh, true);
|
||||
btCompoundShape shape;
|
||||
shape.addChildShape(btTransform::getIdentity(), &triangle);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
|
@ -214,9 +211,9 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
0, 3, 0,
|
||||
0, 3, 4,
|
||||
2, 3, 0,
|
||||
0, 0, 3,
|
||||
0, 4, 3,
|
||||
2, 0, 3,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -230,7 +227,7 @@ namespace
|
|||
btCompoundShape shape;
|
||||
shape.addChildShape(btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
&triangle);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||
|
@ -238,9 +235,9 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
1, 12, 2,
|
||||
1, 12, 10,
|
||||
3, 12, 2,
|
||||
1, 2, 12,
|
||||
1, 10, 12,
|
||||
3, 2, 12,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -252,7 +249,7 @@ namespace
|
|||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||
mesh.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform::getIdentity(),
|
||||
|
@ -260,12 +257,12 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-3, 0, -3,
|
||||
-3, 0, -2,
|
||||
-2, 0, -3,
|
||||
-1, 0, -1,
|
||||
-1, 0, 1,
|
||||
1, 0, -1,
|
||||
-3, -3, 0,
|
||||
-3, -2, 0,
|
||||
-2, -3, 0,
|
||||
-1, -1, 0,
|
||||
-1, 1, 0,
|
||||
1, -1, 0,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0, 5, 4, 3}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>(2, AreaType_ground));
|
||||
|
@ -273,14 +270,13 @@ namespace
|
|||
|
||||
TEST_F(DetourNavigatorRecastMeshBuilderTest, with_bounds_add_bhv_triangle_shape_should_filter_by_bounds)
|
||||
{
|
||||
mSettings.mRecastScaleFactor = 0.1f;
|
||||
mBounds.mMin = osg::Vec2f(-3, -3) * mSettings.mRecastScaleFactor;
|
||||
mBounds.mMax = osg::Vec2f(-2, -2) * mSettings.mRecastScaleFactor;
|
||||
mBounds.mMin = osg::Vec2f(-3, -3);
|
||||
mBounds.mMax = osg::Vec2f(-2, -2);
|
||||
btTriangleMesh mesh;
|
||||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||
mesh.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform::getIdentity(),
|
||||
|
@ -288,9 +284,9 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-0.3f, 0, -0.3f,
|
||||
-0.3f, 0, -0.2f,
|
||||
-0.2f, 0, -0.3f,
|
||||
-3, -3, 0,
|
||||
-3, -2, 0,
|
||||
-2, -3, 0,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -304,7 +300,7 @@ namespace
|
|||
mesh.addTriangle(btVector3(0, -1, -1), btVector3(0, -1, -1), btVector3(0, 1, -1));
|
||||
mesh.addTriangle(btVector3(0, -3, -3), btVector3(0, -3, -2), btVector3(0, -2, -3));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btQuaternion(btVector3(1, 0, 0),
|
||||
|
@ -313,11 +309,11 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||
0, -0.707106769084930419921875, -3.535533905029296875,
|
||||
0, 4.44089209850062616169452667236328125e-16, -4.24264049530029296875,
|
||||
0, 0.707106769084930419921875, -3.535533905029296875,
|
||||
0, -4.24264049530029296875, 4.44089209850062616169452667236328125e-16,
|
||||
0, -3.535533905029296875, -0.707106769084930419921875,
|
||||
0, -3.535533905029296875, 0.707106769084930419921875,
|
||||
}))) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({0, 2, 1}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({1, 2, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
}
|
||||
|
||||
|
@ -329,7 +325,7 @@ namespace
|
|||
mesh.addTriangle(btVector3(-1, 0, -1), btVector3(-1, 0, 1), btVector3(1, 0, -1));
|
||||
mesh.addTriangle(btVector3(-3, 0, -3), btVector3(-3, 0, -2), btVector3(-2, 0, -3));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btQuaternion(btVector3(0, 1, 0),
|
||||
|
@ -338,9 +334,9 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||
-4.24264049530029296875, 4.44089209850062616169452667236328125e-16, 0,
|
||||
-3.535533905029296875, -0.707106769084930419921875, 0,
|
||||
-3.535533905029296875, 0.707106769084930419921875, 0,
|
||||
-4.24264049530029296875, 0, 4.44089209850062616169452667236328125e-16,
|
||||
-3.535533905029296875, 0, -0.707106769084930419921875,
|
||||
-3.535533905029296875, 0, 0.707106769084930419921875,
|
||||
}))) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({1, 2, 0}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -354,7 +350,7 @@ namespace
|
|||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||
mesh.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape),
|
||||
btTransform(btQuaternion(btVector3(0, 0, 1),
|
||||
|
@ -363,9 +359,9 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||
-1.41421353816986083984375, 0, -1.1102230246251565404236316680908203125e-16,
|
||||
1.1102230246251565404236316680908203125e-16, 0, -1.41421353816986083984375,
|
||||
1.41421353816986083984375, 0, 1.1102230246251565404236316680908203125e-16,
|
||||
-1.41421353816986083984375, -1.1102230246251565404236316680908203125e-16, 0,
|
||||
1.1102230246251565404236316680908203125e-16, -1.41421353816986083984375, 0,
|
||||
1.41421353816986083984375, 1.1102230246251565404236316680908203125e-16, 0,
|
||||
}))) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 0, 1}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||
|
@ -379,7 +375,7 @@ namespace
|
|||
btTriangleMesh mesh2;
|
||||
mesh2.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||
btBvhTriangleMeshShape shape2(&mesh2, true);
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(
|
||||
static_cast<const btCollisionShape&>(shape1),
|
||||
btTransform::getIdentity(),
|
||||
|
@ -392,12 +388,12 @@ namespace
|
|||
);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-3, 0, -3,
|
||||
-3, 0, -2,
|
||||
-2, 0, -3,
|
||||
-1, 0, -1,
|
||||
-1, 0, 1,
|
||||
1, 0, -1,
|
||||
-3, -3, 0,
|
||||
-3, -2, 0,
|
||||
-2, -3, 0,
|
||||
-1, -1, 0,
|
||||
-1, 1, 0,
|
||||
1, -1, 0,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0, 5, 4, 3}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_null, AreaType_ground}));
|
||||
|
@ -405,7 +401,7 @@ namespace
|
|||
|
||||
TEST_F(DetourNavigatorRecastMeshBuilderTest, add_water_then_get_water_should_return_it)
|
||||
{
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addWater(1000, btTransform(btMatrix3x3::getIdentity(), btVector3(100, 200, 300)));
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getWater(), std::vector<RecastMesh::Water>({
|
||||
|
@ -420,14 +416,14 @@ namespace
|
|||
mesh.addTriangle(btVector3(1, 1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||
btBvhTriangleMeshShape shape(&mesh, true);
|
||||
|
||||
RecastMeshBuilder builder(mSettings, mBounds);
|
||||
RecastMeshBuilder builder(mBounds);
|
||||
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||
-1, 0, -1,
|
||||
-1, 0, 1,
|
||||
1, 0, -1,
|
||||
1, 0, 1,
|
||||
-1, -1, 0,
|
||||
-1, 1, 0,
|
||||
1, -1, 0,
|
||||
1, 1, 0,
|
||||
})) << recastMesh->getMesh().getVertices();
|
||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0, 2, 1, 3}));
|
||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground, AreaType_ground}));
|
||||
|
|
|
@ -157,15 +157,23 @@ namespace
|
|||
throw NavigatorException("Failed to create heightfield for navmesh");
|
||||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const Mesh& mesh, const rcConfig& config,
|
||||
bool rasterizeTriangles(rcContext& context, const Mesh& mesh, const Settings& settings, const rcConfig& config,
|
||||
rcHeightfield& solid)
|
||||
{
|
||||
std::vector<unsigned char> areas(mesh.getAreaTypes().begin(), mesh.getAreaTypes().end());
|
||||
std::vector<float> vertices = mesh.getVertices();
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); i += 3)
|
||||
{
|
||||
for (std::size_t j = 0; j < 3; ++j)
|
||||
vertices[i + j] = toNavMeshCoordinates(settings, vertices[i + j]);
|
||||
std::swap(vertices[i + 1], vertices[i + 2]);
|
||||
}
|
||||
|
||||
rcClearUnwalkableTriangles(
|
||||
&context,
|
||||
config.walkableSlopeAngle,
|
||||
mesh.getVertices().data(),
|
||||
vertices.data(),
|
||||
static_cast<int>(mesh.getVerticesCount()),
|
||||
mesh.getIndices().data(),
|
||||
static_cast<int>(areas.size()),
|
||||
|
@ -174,7 +182,7 @@ namespace
|
|||
|
||||
return rcRasterizeTriangles(
|
||||
&context,
|
||||
mesh.getVertices().data(),
|
||||
vertices.data(),
|
||||
static_cast<int>(mesh.getVerticesCount()),
|
||||
mesh.getIndices().data(),
|
||||
areas.data(),
|
||||
|
@ -242,7 +250,7 @@ namespace
|
|||
bool rasterizeTriangles(rcContext& context, const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh,
|
||||
const rcConfig& config, const Settings& settings, rcHeightfield& solid)
|
||||
{
|
||||
if (!rasterizeTriangles(context, recastMesh.getMesh(), config, solid))
|
||||
if (!rasterizeTriangles(context, recastMesh.getMesh(), settings, config, solid))
|
||||
return false;
|
||||
|
||||
rasterizeWaterTriangles(context, agentHalfExtents, recastMesh, settings, config, solid);
|
||||
|
@ -491,6 +499,8 @@ namespace DetourNavigator
|
|||
}
|
||||
|
||||
auto recastMeshBounds = recastMesh->getBounds();
|
||||
recastMeshBounds.mMin = toNavMeshCoordinates(settings, recastMeshBounds.mMin);
|
||||
recastMeshBounds.mMax = toNavMeshCoordinates(settings, recastMeshBounds.mMax);
|
||||
|
||||
for (const auto& water : recastMesh->getWater())
|
||||
{
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#include "recastmeshbuilder.hpp"
|
||||
#include "debug.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "settingsutils.hpp"
|
||||
#include "exceptions.hpp"
|
||||
|
||||
#include <components/bullethelpers/transformboundingbox.hpp>
|
||||
#include <components/bullethelpers/processtrianglecallback.hpp>
|
||||
#include <components/misc/convert.hpp>
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
||||
|
@ -26,12 +25,12 @@ namespace DetourNavigator
|
|||
|
||||
namespace
|
||||
{
|
||||
RecastMeshTriangle makeRecastMeshTriangle(const btVector3* vertices, const AreaType areaType, const Settings& settings)
|
||||
RecastMeshTriangle makeRecastMeshTriangle(const btVector3* vertices, const AreaType areaType)
|
||||
{
|
||||
RecastMeshTriangle result;
|
||||
result.mAreaType = areaType;
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
result.mVertices[i] = toNavMeshCoordinates(settings, Misc::Convert::makeOsgVec3f(vertices[i]));
|
||||
result.mVertices[i] = Misc::Convert::makeOsgVec3f(vertices[i]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -81,12 +80,9 @@ namespace DetourNavigator
|
|||
return Mesh(std::move(indices), std::move(vertices), std::move(areaTypes));
|
||||
}
|
||||
|
||||
RecastMeshBuilder::RecastMeshBuilder(const Settings& settings, const TileBounds& bounds)
|
||||
: mSettings(settings)
|
||||
, mBounds(bounds)
|
||||
RecastMeshBuilder::RecastMeshBuilder(const TileBounds& bounds) noexcept
|
||||
: mBounds(bounds)
|
||||
{
|
||||
mBounds.mMin /= mSettings.get().mRecastScaleFactor;
|
||||
mBounds.mMax /= mSettings.get().mRecastScaleFactor;
|
||||
}
|
||||
|
||||
void RecastMeshBuilder::addObject(const btCollisionShape& shape, const btTransform& transform,
|
||||
|
@ -117,7 +113,7 @@ namespace DetourNavigator
|
|||
{
|
||||
return addObject(shape, transform, makeProcessTriangleCallback([&] (btVector3* vertices, int, int)
|
||||
{
|
||||
RecastMeshTriangle triangle = makeRecastMeshTriangle(vertices, areaType, mSettings);
|
||||
RecastMeshTriangle triangle = makeRecastMeshTriangle(vertices, areaType);
|
||||
std::reverse(triangle.mVertices.begin(), triangle.mVertices.end());
|
||||
mTriangles.emplace_back(triangle);
|
||||
}));
|
||||
|
@ -128,7 +124,7 @@ namespace DetourNavigator
|
|||
{
|
||||
return addObject(shape, transform, makeProcessTriangleCallback([&] (btVector3* vertices, int, int)
|
||||
{
|
||||
mTriangles.emplace_back(makeRecastMeshTriangle(vertices, areaType, mSettings));
|
||||
mTriangles.emplace_back(makeRecastMeshTriangle(vertices, areaType));
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -158,7 +154,7 @@ namespace DetourNavigator
|
|||
shape.getVertex(indices[i + j], position);
|
||||
vertices[j] = transform(position);
|
||||
}
|
||||
mTriangles.emplace_back(makeRecastMeshTriangle(vertices.data(), areaType, mSettings));
|
||||
mTriangles.emplace_back(makeRecastMeshTriangle(vertices.data(), areaType));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@ class btTriangleCallback;
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct Settings;
|
||||
|
||||
struct RecastMeshTriangle
|
||||
{
|
||||
AreaType mAreaType;
|
||||
|
@ -39,7 +37,7 @@ namespace DetourNavigator
|
|||
class RecastMeshBuilder
|
||||
{
|
||||
public:
|
||||
RecastMeshBuilder(const Settings& settings, const TileBounds& bounds);
|
||||
explicit RecastMeshBuilder(const TileBounds& bounds) noexcept;
|
||||
|
||||
void addObject(const btCollisionShape& shape, const btTransform& transform, const AreaType areaType);
|
||||
|
||||
|
@ -56,8 +54,7 @@ namespace DetourNavigator
|
|||
std::shared_ptr<RecastMesh> create(std::size_t generation, std::size_t revision) &&;
|
||||
|
||||
private:
|
||||
std::reference_wrapper<const Settings> mSettings;
|
||||
TileBounds mBounds;
|
||||
const TileBounds mBounds;
|
||||
std::vector<RecastMeshTriangle> mTriangles;
|
||||
std::vector<RecastMesh::Water> mWater;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "recastmeshmanager.hpp"
|
||||
#include "recastmeshbuilder.hpp"
|
||||
#include "settings.hpp"
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
|
@ -68,7 +69,10 @@ namespace DetourNavigator
|
|||
|
||||
std::shared_ptr<RecastMesh> RecastMeshManager::getMesh()
|
||||
{
|
||||
RecastMeshBuilder builder(mSettings, mTileBounds);
|
||||
TileBounds tileBounds = mTileBounds;
|
||||
tileBounds.mMin /= mSettings.mRecastScaleFactor;
|
||||
tileBounds.mMax /= mSettings.mRecastScaleFactor;
|
||||
RecastMeshBuilder builder(tileBounds);
|
||||
for (const auto& [k, v] : mWater)
|
||||
builder.addWater(v.mCellSize, v.mTransform);
|
||||
for (const auto& [k, object] : mObjects)
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
#include <osg/Group>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<float> calculateNormals(const std::vector<float>& vertices, const std::vector<int>& indices)
|
||||
|
@ -37,13 +40,20 @@ namespace SceneUtil
|
|||
osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
|
||||
const DetourNavigator::Settings& settings)
|
||||
{
|
||||
using namespace DetourNavigator;
|
||||
|
||||
const osg::ref_ptr<osg::Group> group(new osg::Group);
|
||||
DebugDraw debugDraw(*group, osg::Vec3f(0, 0, 0), 1.0f / settings.mRecastScaleFactor);
|
||||
DebugDraw debugDraw(*group, osg::Vec3f(0, 0, 0), 1.0f);
|
||||
const DetourNavigator::Mesh& mesh = recastMesh.getMesh();
|
||||
const auto normals = calculateNormals(mesh.getVertices(), mesh.getIndices());
|
||||
std::vector<float> vertices = mesh.getVertices();
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); i += 3)
|
||||
std::swap(vertices[i + 1], vertices[i + 2]);
|
||||
|
||||
const auto normals = calculateNormals(vertices, mesh.getIndices());
|
||||
const auto texScale = 1.0f / (settings.mCellSize * 10.0f);
|
||||
duDebugDrawTriMesh(&debugDraw, mesh.getVertices().data(), mesh.getVerticesCount(),
|
||||
mesh.getIndices().data(), normals.data(), mesh.getTrianglesCount(), nullptr, texScale);
|
||||
duDebugDrawTriMesh(&debugDraw, vertices.data(), static_cast<int>(vertices.size() / 3),
|
||||
mesh.getIndices().data(), normals.data(), static_cast<int>(mesh.getIndices().size() / 3), nullptr, texScale);
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue