mirror of
https://github.com/OpenMW/openmw.git
synced 2025-11-08 17:16:42 +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 "operators.hpp"
|
||||||
|
|
||||||
#include <components/detournavigator/recastmeshbuilder.hpp>
|
#include <components/detournavigator/recastmeshbuilder.hpp>
|
||||||
#include <components/detournavigator/settings.hpp>
|
|
||||||
#include <components/detournavigator/recastmesh.hpp>
|
#include <components/detournavigator/recastmesh.hpp>
|
||||||
#include <components/detournavigator/exceptions.hpp>
|
#include <components/detournavigator/exceptions.hpp>
|
||||||
|
|
||||||
|
|
@ -33,14 +32,12 @@ namespace
|
||||||
|
|
||||||
struct DetourNavigatorRecastMeshBuilderTest : Test
|
struct DetourNavigatorRecastMeshBuilderTest : Test
|
||||||
{
|
{
|
||||||
Settings mSettings;
|
|
||||||
TileBounds mBounds;
|
TileBounds mBounds;
|
||||||
const std::size_t mGeneration = 0;
|
const std::size_t mGeneration = 0;
|
||||||
const std::size_t mRevision = 0;
|
const std::size_t mRevision = 0;
|
||||||
|
|
||||||
DetourNavigatorRecastMeshBuilderTest()
|
DetourNavigatorRecastMeshBuilderTest()
|
||||||
{
|
{
|
||||||
mSettings.mRecastScaleFactor = 1.0f;
|
|
||||||
mBounds.mMin = osg::Vec2f(-std::numeric_limits<float>::max() * std::numeric_limits<float>::epsilon(),
|
mBounds.mMin = osg::Vec2f(-std::numeric_limits<float>::max() * std::numeric_limits<float>::epsilon(),
|
||||||
-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(),
|
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)
|
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);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>());
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>());
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>());
|
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));
|
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
|
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
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);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-1, 0, -1,
|
-1, -1, 0,
|
||||||
-1, 0, 1,
|
-1, 1, 0,
|
||||||
1, 0, -1,
|
1, -1, 0,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||||
|
|
@ -80,7 +77,7 @@ namespace
|
||||||
btTriangleMesh mesh;
|
btTriangleMesh mesh;
|
||||||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
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);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
0, 3, 0,
|
0, 0, 3,
|
||||||
0, 3, 4,
|
0, 4, 3,
|
||||||
2, 3, 0,
|
2, 0, 3,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
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}};
|
const std::array<btScalar, 4> heightfieldData {{0, 0, 0, 0}};
|
||||||
btHeightfieldTerrainShape shape(2, 2, heightfieldData.data(), 1, 0, 0, 2, PHY_FLOAT, false);
|
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);
|
builder.addObject(static_cast<const btCollisionShape&>(shape), btTransform::getIdentity(), AreaType_ground);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-0.5, 0, -0.5,
|
-0.5, -0.5, 0,
|
||||||
-0.5, 0, 0.5,
|
-0.5, 0.5, 0,
|
||||||
0.5, 0, -0.5,
|
0.5, -0.5, 0,
|
||||||
0.5, 0, 0.5,
|
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().getIndices(), std::vector<int>({0, 1, 2, 2, 1, 3}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground, AreaType_ground}));
|
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)
|
TEST_F(DetourNavigatorRecastMeshBuilderTest, add_box_shape_should_produce_12_triangles)
|
||||||
{
|
{
|
||||||
btBoxShape shape(btVector3(1, 1, 2));
|
btBoxShape shape(btVector3(1, 1, 2));
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
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);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-1, -2, -1,
|
-1, -1, -2,
|
||||||
-1, -2, 1,
|
-1, -1, 2,
|
||||||
-1, 2, -1,
|
-1, 1, -2,
|
||||||
-1, 2, 1,
|
-1, 1, 2,
|
||||||
1, -2, -1,
|
1, -1, -2,
|
||||||
1, -2, 1,
|
1, -1, 2,
|
||||||
1, 2, -1,
|
1, 1, -2,
|
||||||
1, 2, 1,
|
1, 1, 2,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({
|
||||||
0, 1, 3,
|
0, 1, 5,
|
||||||
0, 2, 6,
|
0, 2, 3,
|
||||||
0, 4, 5,
|
0, 4, 6,
|
||||||
1, 5, 7,
|
1, 3, 7,
|
||||||
2, 3, 7,
|
2, 6, 7,
|
||||||
3, 2, 0,
|
3, 1, 0,
|
||||||
4, 6, 7,
|
4, 5, 7,
|
||||||
5, 1, 0,
|
5, 4, 0,
|
||||||
6, 4, 0,
|
6, 2, 0,
|
||||||
7, 3, 1,
|
7, 3, 2,
|
||||||
7, 5, 4,
|
7, 5, 1,
|
||||||
7, 6, 2,
|
7, 6, 4,
|
||||||
})) << recastMesh->getMesh().getIndices();
|
})) << recastMesh->getMesh().getIndices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>(12, AreaType_ground));
|
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(), &triangle1);
|
||||||
shape.addChildShape(btTransform::getIdentity(), &box);
|
shape.addChildShape(btTransform::getIdentity(), &box);
|
||||||
shape.addChildShape(btTransform::getIdentity(), &triangle2);
|
shape.addChildShape(btTransform::getIdentity(), &triangle2);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform::getIdentity(),
|
btTransform::getIdentity(),
|
||||||
|
|
@ -167,34 +164,34 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-1, -2, -1,
|
-1, -1, -2,
|
||||||
-1, -2, 1,
|
-1, -1, 0,
|
||||||
-1, 0, -1,
|
-1, -1, 2,
|
||||||
-1, 0, 1,
|
-1, 1, -2,
|
||||||
-1, 2, -1,
|
-1, 1, 0,
|
||||||
-1, 2, 1,
|
-1, 1, 2,
|
||||||
1, -2, -1,
|
1, -1, -2,
|
||||||
1, -2, 1,
|
1, -1, 0,
|
||||||
1, 0, -1,
|
1, -1, 2,
|
||||||
1, 0, 1,
|
1, 1, -2,
|
||||||
1, 2, -1,
|
1, 1, 0,
|
||||||
1, 2, 1,
|
1, 1, 2,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({
|
||||||
0, 1, 5,
|
0, 2, 8,
|
||||||
0, 4, 10,
|
0, 3, 5,
|
||||||
0, 6, 7,
|
0, 6, 9,
|
||||||
1, 7, 11,
|
2, 5, 11,
|
||||||
4, 5, 11,
|
3, 9, 11,
|
||||||
5, 4, 0,
|
5, 2, 0,
|
||||||
6, 10, 11,
|
6, 8, 11,
|
||||||
7, 1, 0,
|
7, 4, 1,
|
||||||
8, 3, 2,
|
7, 4, 10,
|
||||||
8, 3, 9,
|
8, 6, 0,
|
||||||
10, 6, 0,
|
9, 3, 0,
|
||||||
11, 5, 1,
|
11, 5, 3,
|
||||||
11, 7, 6,
|
11, 8, 2,
|
||||||
11, 10, 4,
|
11, 9, 6,
|
||||||
})) << recastMesh->getMesh().getIndices();
|
})) << recastMesh->getMesh().getIndices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>(14, AreaType_ground));
|
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>(14, AreaType_ground));
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +203,7 @@ namespace
|
||||||
btBvhTriangleMeshShape triangle(&mesh, true);
|
btBvhTriangleMeshShape triangle(&mesh, true);
|
||||||
btCompoundShape shape;
|
btCompoundShape shape;
|
||||||
shape.addChildShape(btTransform::getIdentity(), &triangle);
|
shape.addChildShape(btTransform::getIdentity(), &triangle);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
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);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
0, 3, 0,
|
0, 0, 3,
|
||||||
0, 3, 4,
|
0, 4, 3,
|
||||||
2, 3, 0,
|
2, 0, 3,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||||
|
|
@ -230,7 +227,7 @@ namespace
|
||||||
btCompoundShape shape;
|
btCompoundShape shape;
|
||||||
shape.addChildShape(btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
shape.addChildShape(btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
||||||
&triangle);
|
&triangle);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform(btMatrix3x3::getIdentity().scaled(btVector3(1, 2, 3)), btVector3(1, 2, 3)),
|
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);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
1, 12, 2,
|
1, 2, 12,
|
||||||
1, 12, 10,
|
1, 10, 12,
|
||||||
3, 12, 2,
|
3, 2, 12,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
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(-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));
|
mesh.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform::getIdentity(),
|
btTransform::getIdentity(),
|
||||||
|
|
@ -260,12 +257,12 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-3, 0, -3,
|
-3, -3, 0,
|
||||||
-3, 0, -2,
|
-3, -2, 0,
|
||||||
-2, 0, -3,
|
-2, -3, 0,
|
||||||
-1, 0, -1,
|
-1, -1, 0,
|
||||||
-1, 0, 1,
|
-1, 1, 0,
|
||||||
1, 0, -1,
|
1, -1, 0,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0, 5, 4, 3}));
|
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));
|
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)
|
TEST_F(DetourNavigatorRecastMeshBuilderTest, with_bounds_add_bhv_triangle_shape_should_filter_by_bounds)
|
||||||
{
|
{
|
||||||
mSettings.mRecastScaleFactor = 0.1f;
|
mBounds.mMin = osg::Vec2f(-3, -3);
|
||||||
mBounds.mMin = osg::Vec2f(-3, -3) * mSettings.mRecastScaleFactor;
|
mBounds.mMax = osg::Vec2f(-2, -2);
|
||||||
mBounds.mMax = osg::Vec2f(-2, -2) * mSettings.mRecastScaleFactor;
|
|
||||||
btTriangleMesh mesh;
|
btTriangleMesh mesh;
|
||||||
mesh.addTriangle(btVector3(-1, -1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
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));
|
mesh.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform::getIdentity(),
|
btTransform::getIdentity(),
|
||||||
|
|
@ -288,9 +284,9 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-0.3f, 0, -0.3f,
|
-3, -3, 0,
|
||||||
-0.3f, 0, -0.2f,
|
-3, -2, 0,
|
||||||
-0.2f, 0, -0.3f,
|
-2, -3, 0,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
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, -1, -1), btVector3(0, -1, -1), btVector3(0, 1, -1));
|
||||||
mesh.addTriangle(btVector3(0, -3, -3), btVector3(0, -3, -2), btVector3(0, -2, -3));
|
mesh.addTriangle(btVector3(0, -3, -3), btVector3(0, -3, -2), btVector3(0, -2, -3));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform(btQuaternion(btVector3(1, 0, 0),
|
btTransform(btQuaternion(btVector3(1, 0, 0),
|
||||||
|
|
@ -313,11 +309,11 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||||
0, -0.707106769084930419921875, -3.535533905029296875,
|
0, -4.24264049530029296875, 4.44089209850062616169452667236328125e-16,
|
||||||
0, 4.44089209850062616169452667236328125e-16, -4.24264049530029296875,
|
0, -3.535533905029296875, -0.707106769084930419921875,
|
||||||
0, 0.707106769084930419921875, -3.535533905029296875,
|
0, -3.535533905029296875, 0.707106769084930419921875,
|
||||||
}))) << recastMesh->getMesh().getVertices();
|
}))) << 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}));
|
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(-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));
|
mesh.addTriangle(btVector3(-3, 0, -3), btVector3(-3, 0, -2), btVector3(-2, 0, -3));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform(btQuaternion(btVector3(0, 1, 0),
|
btTransform(btQuaternion(btVector3(0, 1, 0),
|
||||||
|
|
@ -338,9 +334,9 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||||
-4.24264049530029296875, 4.44089209850062616169452667236328125e-16, 0,
|
-4.24264049530029296875, 0, 4.44089209850062616169452667236328125e-16,
|
||||||
-3.535533905029296875, -0.707106769084930419921875, 0,
|
-3.535533905029296875, 0, -0.707106769084930419921875,
|
||||||
-3.535533905029296875, 0.707106769084930419921875, 0,
|
-3.535533905029296875, 0, 0.707106769084930419921875,
|
||||||
}))) << recastMesh->getMesh().getVertices();
|
}))) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({1, 2, 0}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({1, 2, 0}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
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(-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));
|
mesh.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape),
|
static_cast<const btCollisionShape&>(shape),
|
||||||
btTransform(btQuaternion(btVector3(0, 0, 1),
|
btTransform(btQuaternion(btVector3(0, 0, 1),
|
||||||
|
|
@ -363,9 +359,9 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
EXPECT_THAT(recastMesh->getMesh().getVertices(), Pointwise(FloatNear(1e-5), std::vector<float>({
|
||||||
-1.41421353816986083984375, 0, -1.1102230246251565404236316680908203125e-16,
|
-1.41421353816986083984375, -1.1102230246251565404236316680908203125e-16, 0,
|
||||||
1.1102230246251565404236316680908203125e-16, 0, -1.41421353816986083984375,
|
1.1102230246251565404236316680908203125e-16, -1.41421353816986083984375, 0,
|
||||||
1.41421353816986083984375, 0, 1.1102230246251565404236316680908203125e-16,
|
1.41421353816986083984375, 1.1102230246251565404236316680908203125e-16, 0,
|
||||||
}))) << recastMesh->getMesh().getVertices();
|
}))) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 0, 1}));
|
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 0, 1}));
|
||||||
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
EXPECT_EQ(recastMesh->getMesh().getAreaTypes(), std::vector<AreaType>({AreaType_ground}));
|
||||||
|
|
@ -379,7 +375,7 @@ namespace
|
||||||
btTriangleMesh mesh2;
|
btTriangleMesh mesh2;
|
||||||
mesh2.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
mesh2.addTriangle(btVector3(-3, -3, 0), btVector3(-3, -2, 0), btVector3(-2, -3, 0));
|
||||||
btBvhTriangleMeshShape shape2(&mesh2, true);
|
btBvhTriangleMeshShape shape2(&mesh2, true);
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
RecastMeshBuilder builder(mBounds);
|
||||||
builder.addObject(
|
builder.addObject(
|
||||||
static_cast<const btCollisionShape&>(shape1),
|
static_cast<const btCollisionShape&>(shape1),
|
||||||
btTransform::getIdentity(),
|
btTransform::getIdentity(),
|
||||||
|
|
@ -392,12 +388,12 @@ namespace
|
||||||
);
|
);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-3, 0, -3,
|
-3, -3, 0,
|
||||||
-3, 0, -2,
|
-3, -2, 0,
|
||||||
-2, 0, -3,
|
-2, -3, 0,
|
||||||
-1, 0, -1,
|
-1, -1, 0,
|
||||||
-1, 0, 1,
|
-1, 1, 0,
|
||||||
1, 0, -1,
|
1, -1, 0,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0, 5, 4, 3}));
|
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}));
|
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)
|
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)));
|
builder.addWater(1000, btTransform(btMatrix3x3::getIdentity(), btVector3(100, 200, 300)));
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getWater(), std::vector<RecastMesh::Water>({
|
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));
|
mesh.addTriangle(btVector3(1, 1, 0), btVector3(-1, 1, 0), btVector3(1, -1, 0));
|
||||||
btBvhTriangleMeshShape shape(&mesh, true);
|
btBvhTriangleMeshShape shape(&mesh, true);
|
||||||
|
|
||||||
RecastMeshBuilder builder(mSettings, mBounds);
|
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);
|
||||||
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
const auto recastMesh = std::move(builder).create(mGeneration, mRevision);
|
||||||
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
EXPECT_EQ(recastMesh->getMesh().getVertices(), std::vector<float>({
|
||||||
-1, 0, -1,
|
-1, -1, 0,
|
||||||
-1, 0, 1,
|
-1, 1, 0,
|
||||||
1, 0, -1,
|
1, -1, 0,
|
||||||
1, 0, 1,
|
1, 1, 0,
|
||||||
})) << recastMesh->getMesh().getVertices();
|
})) << recastMesh->getMesh().getVertices();
|
||||||
EXPECT_EQ(recastMesh->getMesh().getIndices(), std::vector<int>({2, 1, 0, 2, 1, 3}));
|
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}));
|
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");
|
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)
|
rcHeightfield& solid)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> areas(mesh.getAreaTypes().begin(), mesh.getAreaTypes().end());
|
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(
|
rcClearUnwalkableTriangles(
|
||||||
&context,
|
&context,
|
||||||
config.walkableSlopeAngle,
|
config.walkableSlopeAngle,
|
||||||
mesh.getVertices().data(),
|
vertices.data(),
|
||||||
static_cast<int>(mesh.getVerticesCount()),
|
static_cast<int>(mesh.getVerticesCount()),
|
||||||
mesh.getIndices().data(),
|
mesh.getIndices().data(),
|
||||||
static_cast<int>(areas.size()),
|
static_cast<int>(areas.size()),
|
||||||
|
|
@ -174,7 +182,7 @@ namespace
|
||||||
|
|
||||||
return rcRasterizeTriangles(
|
return rcRasterizeTriangles(
|
||||||
&context,
|
&context,
|
||||||
mesh.getVertices().data(),
|
vertices.data(),
|
||||||
static_cast<int>(mesh.getVerticesCount()),
|
static_cast<int>(mesh.getVerticesCount()),
|
||||||
mesh.getIndices().data(),
|
mesh.getIndices().data(),
|
||||||
areas.data(),
|
areas.data(),
|
||||||
|
|
@ -242,7 +250,7 @@ namespace
|
||||||
bool rasterizeTriangles(rcContext& context, const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh,
|
bool rasterizeTriangles(rcContext& context, const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh,
|
||||||
const rcConfig& config, const Settings& settings, rcHeightfield& solid)
|
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;
|
return false;
|
||||||
|
|
||||||
rasterizeWaterTriangles(context, agentHalfExtents, recastMesh, settings, config, solid);
|
rasterizeWaterTriangles(context, agentHalfExtents, recastMesh, settings, config, solid);
|
||||||
|
|
@ -491,6 +499,8 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
auto recastMeshBounds = recastMesh->getBounds();
|
auto recastMeshBounds = recastMesh->getBounds();
|
||||||
|
recastMeshBounds.mMin = toNavMeshCoordinates(settings, recastMeshBounds.mMin);
|
||||||
|
recastMeshBounds.mMax = toNavMeshCoordinates(settings, recastMeshBounds.mMax);
|
||||||
|
|
||||||
for (const auto& water : recastMesh->getWater())
|
for (const auto& water : recastMesh->getWater())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#include "recastmeshbuilder.hpp"
|
#include "recastmeshbuilder.hpp"
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "settings.hpp"
|
|
||||||
#include "settingsutils.hpp"
|
|
||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
|
|
||||||
#include <components/bullethelpers/transformboundingbox.hpp>
|
#include <components/bullethelpers/transformboundingbox.hpp>
|
||||||
#include <components/bullethelpers/processtrianglecallback.hpp>
|
#include <components/bullethelpers/processtrianglecallback.hpp>
|
||||||
#include <components/misc/convert.hpp>
|
#include <components/misc/convert.hpp>
|
||||||
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
||||||
|
|
@ -26,12 +25,12 @@ namespace DetourNavigator
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
RecastMeshTriangle makeRecastMeshTriangle(const btVector3* vertices, const AreaType areaType, const Settings& settings)
|
RecastMeshTriangle makeRecastMeshTriangle(const btVector3* vertices, const AreaType areaType)
|
||||||
{
|
{
|
||||||
RecastMeshTriangle result;
|
RecastMeshTriangle result;
|
||||||
result.mAreaType = areaType;
|
result.mAreaType = areaType;
|
||||||
for (std::size_t i = 0; i < 3; ++i)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,12 +80,9 @@ namespace DetourNavigator
|
||||||
return Mesh(std::move(indices), std::move(vertices), std::move(areaTypes));
|
return Mesh(std::move(indices), std::move(vertices), std::move(areaTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
RecastMeshBuilder::RecastMeshBuilder(const Settings& settings, const TileBounds& bounds)
|
RecastMeshBuilder::RecastMeshBuilder(const TileBounds& bounds) noexcept
|
||||||
: mSettings(settings)
|
: mBounds(bounds)
|
||||||
, mBounds(bounds)
|
|
||||||
{
|
{
|
||||||
mBounds.mMin /= mSettings.get().mRecastScaleFactor;
|
|
||||||
mBounds.mMax /= mSettings.get().mRecastScaleFactor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecastMeshBuilder::addObject(const btCollisionShape& shape, const btTransform& transform,
|
void RecastMeshBuilder::addObject(const btCollisionShape& shape, const btTransform& transform,
|
||||||
|
|
@ -117,7 +113,7 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
return addObject(shape, transform, makeProcessTriangleCallback([&] (btVector3* vertices, int, int)
|
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());
|
std::reverse(triangle.mVertices.begin(), triangle.mVertices.end());
|
||||||
mTriangles.emplace_back(triangle);
|
mTriangles.emplace_back(triangle);
|
||||||
}));
|
}));
|
||||||
|
|
@ -128,7 +124,7 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
return addObject(shape, transform, makeProcessTriangleCallback([&] (btVector3* vertices, int, int)
|
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);
|
shape.getVertex(indices[i + j], position);
|
||||||
vertices[j] = transform(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
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
struct Settings;
|
|
||||||
|
|
||||||
struct RecastMeshTriangle
|
struct RecastMeshTriangle
|
||||||
{
|
{
|
||||||
AreaType mAreaType;
|
AreaType mAreaType;
|
||||||
|
|
@ -39,7 +37,7 @@ namespace DetourNavigator
|
||||||
class RecastMeshBuilder
|
class RecastMeshBuilder
|
||||||
{
|
{
|
||||||
public:
|
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);
|
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) &&;
|
std::shared_ptr<RecastMesh> create(std::size_t generation, std::size_t revision) &&;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<const Settings> mSettings;
|
const TileBounds mBounds;
|
||||||
TileBounds mBounds;
|
|
||||||
std::vector<RecastMeshTriangle> mTriangles;
|
std::vector<RecastMeshTriangle> mTriangles;
|
||||||
std::vector<RecastMesh::Water> mWater;
|
std::vector<RecastMesh::Water> mWater;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "recastmeshmanager.hpp"
|
#include "recastmeshmanager.hpp"
|
||||||
#include "recastmeshbuilder.hpp"
|
#include "recastmeshbuilder.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
|
|
@ -68,7 +69,10 @@ namespace DetourNavigator
|
||||||
|
|
||||||
std::shared_ptr<RecastMesh> RecastMeshManager::getMesh()
|
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)
|
for (const auto& [k, v] : mWater)
|
||||||
builder.addWater(v.mCellSize, v.mTransform);
|
builder.addWater(v.mCellSize, v.mTransform);
|
||||||
for (const auto& [k, object] : mObjects)
|
for (const auto& [k, object] : mObjects)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::vector<float> calculateNormals(const std::vector<float>& vertices, const std::vector<int>& indices)
|
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,
|
osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
|
||||||
const DetourNavigator::Settings& settings)
|
const DetourNavigator::Settings& settings)
|
||||||
{
|
{
|
||||||
|
using namespace DetourNavigator;
|
||||||
|
|
||||||
const osg::ref_ptr<osg::Group> group(new osg::Group);
|
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 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);
|
const auto texScale = 1.0f / (settings.mCellSize * 10.0f);
|
||||||
duDebugDrawTriMesh(&debugDraw, mesh.getVertices().data(), mesh.getVerticesCount(),
|
duDebugDrawTriMesh(&debugDraw, vertices.data(), static_cast<int>(vertices.size() / 3),
|
||||||
mesh.getIndices().data(), normals.data(), mesh.getTrianglesCount(), nullptr, texScale);
|
mesh.getIndices().data(), normals.data(), static_cast<int>(mesh.getIndices().size() / 3), nullptr, texScale);
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue