1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-20 06:53:52 +00:00

Merge pull request #2618 from elsid/fix_rope_bridge

Fix objects culling for recast mesh tiles (bug #5216)
This commit is contained in:
Andrei Kortunov 2019-11-30 21:54:14 +04:00 committed by GitHub
commit ae80d8e490
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 25 deletions

View file

@ -361,9 +361,9 @@ namespace
);
const auto recastMesh = builder.create();
EXPECT_EQ(recastMesh->getVertices(), std::vector<float>({
0.707107067108154296875, 0, -3.535533905029296875,
-0.70710659027099609375, 0, -3.535533905029296875,
2.384185791015625e-07, 0, -4.24264049530029296875,
1.41421353816986083984375, 0, 1.1920928955078125e-07,
-1.41421353816986083984375, 0, -1.1920928955078125e-07,
1.1920928955078125e-07, 0, -1.41421353816986083984375,
}));
EXPECT_EQ(recastMesh->getIndices(), std::vector<int>({0, 1, 2}));
EXPECT_EQ(recastMesh->getAreaTypes(), std::vector<AreaType>({AreaType_ground}));

View file

@ -0,0 +1,38 @@
#ifndef OPENMW_COMPONENTS_BULLETHELPERS_TRANSFORMBOUNDINGBOX_H
#define OPENMW_COMPONENTS_BULLETHELPERS_TRANSFORMBOUNDINGBOX_H
#include <LinearMath/btVector3.h>
#include <LinearMath/btTransform.h>
#include <algorithm>
namespace BulletHelpers
{
inline btVector3 min(const btVector3& a, const btVector3& b)
{
return btVector3(std::min(a.x(), b.x()), std::min(a.y(), b.y()), std::min(a.z(), b.z()));
}
inline btVector3 max(const btVector3& a, const btVector3& b)
{
return btVector3(std::max(a.x(), b.x()), std::max(a.y(), b.y()), std::max(a.z(), b.z()));
}
// http://dev.theomader.com/transform-bounding-boxes/
inline void transformBoundingBox(const btTransform& transform, btVector3& aabbMin, btVector3& aabbMax)
{
const btVector3 xa(transform.getBasis().getColumn(0) * aabbMin.x());
const btVector3 xb(transform.getBasis().getColumn(0) * aabbMax.x());
const btVector3 ya(transform.getBasis().getColumn(1) * aabbMin.y());
const btVector3 yb(transform.getBasis().getColumn(1) * aabbMax.y());
const btVector3 za(transform.getBasis().getColumn(2) * aabbMin.z());
const btVector3 zb(transform.getBasis().getColumn(2) * aabbMax.z());
aabbMin = min(xa, xb) + min(ya, yb) + min(za, zb) + transform.getOrigin();
aabbMax = max(xa, xb) + max(ya, yb) + max(za, zb) + transform.getOrigin();
}
}
#endif

View file

@ -135,7 +135,7 @@ namespace DetourNavigator
}
catch (const std::exception& e)
{
Log(Debug::Error) << "AsyncNavMeshUpdater::process exception: ", e.what();
Log(Debug::Error) << "AsyncNavMeshUpdater::process exception: " << e.what();
}
}
Log(Debug::Debug) << "Stop navigator jobs processing";

View file

@ -5,6 +5,7 @@
#include "settingsutils.hpp"
#include "exceptions.hpp"
#include <components/bullethelpers/transformboundingbox.hpp>
#include <components/bullethelpers/processtrianglecallback.hpp>
#include <components/misc/convert.hpp>
@ -13,6 +14,7 @@
#include <BulletCollision/CollisionShapes/btConcaveShape.h>
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include <LinearMath/btTransform.h>
#include <LinearMath/btAabbUtil2.h>
#include <algorithm>
@ -57,7 +59,7 @@ namespace DetourNavigator
return addObject(shape, transform, makeProcessTriangleCallback([&] (btVector3* triangle, int, int)
{
for (std::size_t i = 3; i > 0; --i)
addTriangleVertex(transform(triangle[i - 1]));
addTriangleVertex(triangle[i - 1]);
mAreaTypes.push_back(areaType);
}));
}
@ -68,7 +70,7 @@ namespace DetourNavigator
return addObject(shape, transform, makeProcessTriangleCallback([&] (btVector3* triangle, int, int)
{
for (std::size_t i = 0; i < 3; ++i)
addTriangleVertex(transform(triangle[i]));
addTriangleVertex(triangle[i]);
mAreaTypes.push_back(areaType);
}));
}
@ -131,8 +133,34 @@ namespace DetourNavigator
shape.getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
aabbMin = transform(aabbMin);
aabbMax = transform(aabbMax);
const btVector3 boundsMin(mBounds.mMin.x(), mBounds.mMin.y(),
-std::numeric_limits<btScalar>::max() * std::numeric_limits<btScalar>::epsilon());
const btVector3 boundsMax(mBounds.mMax.x(), mBounds.mMax.y(),
std::numeric_limits<btScalar>::max() * std::numeric_limits<btScalar>::epsilon());
auto wrapper = makeProcessTriangleCallback([&] (btVector3* triangle, int partId, int triangleIndex)
{
std::array<btVector3, 3> transformed;
for (std::size_t i = 0; i < 3; ++i)
transformed[i] = transform(triangle[i]);
if (TestTriangleAgainstAabb2(transformed.data(), boundsMin, boundsMax))
callback.processTriangle(transformed.data(), partId, triangleIndex);
});
shape.processAllTriangles(&wrapper, aabbMin, aabbMax);
}
void RecastMeshBuilder::addObject(const btHeightfieldTerrainShape& shape, const btTransform& transform,
btTriangleCallback&& callback)
{
using BulletHelpers::transformBoundingBox;
btVector3 aabbMin;
btVector3 aabbMax;
shape.getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
transformBoundingBox(transform, aabbMin, aabbMax);
aabbMin.setX(std::max(mBounds.mMin.x(), aabbMin.x()));
aabbMin.setX(std::min(mBounds.mMax.x(), aabbMin.x()));
@ -144,20 +172,17 @@ namespace DetourNavigator
aabbMax.setY(std::max(mBounds.mMin.y(), aabbMax.y()));
aabbMax.setY(std::min(mBounds.mMax.y(), aabbMax.y()));
const auto inversedTransform = transform.inverse();
transformBoundingBox(transform.inverse(), aabbMin, aabbMax);
aabbMin = inversedTransform(aabbMin);
aabbMax = inversedTransform(aabbMax);
auto wrapper = makeProcessTriangleCallback([&] (btVector3* triangle, int partId, int triangleIndex)
{
std::array<btVector3, 3> transformed;
for (std::size_t i = 0; i < 3; ++i)
transformed[i] = transform(triangle[i]);
callback.processTriangle(transformed.data(), partId, triangleIndex);
});
aabbMin.setX(std::min(aabbMin.x(), aabbMax.x()));
aabbMin.setY(std::min(aabbMin.y(), aabbMax.y()));
aabbMin.setZ(std::min(aabbMin.z(), aabbMax.z()));
aabbMax.setX(std::max(aabbMin.x(), aabbMax.x()));
aabbMax.setY(std::max(aabbMin.y(), aabbMax.y()));
aabbMax.setZ(std::max(aabbMin.z(), aabbMax.z()));
shape.processAllTriangles(&callback, aabbMin, aabbMax);
shape.processAllTriangles(&wrapper, aabbMin, aabbMax);
}
void RecastMeshBuilder::addTriangleVertex(const btVector3& worldPosition)

View file

@ -48,6 +48,8 @@ namespace DetourNavigator
void addObject(const btConcaveShape& shape, const btTransform& transform, btTriangleCallback&& callback);
void addObject(const btHeightfieldTerrainShape& shape, const btTransform& transform, btTriangleCallback&& callback);
void addTriangleVertex(const btVector3& worldPosition);
void addVertex(const btVector3& worldPosition);

View file

@ -176,12 +176,12 @@ recast scale factor
:Type: floating point
:Range: > 0.0
:Default: 0.023529411764705882
:Default: 0.029411764705882353
Scale of nav mesh coordinates to world coordinates. Recastnavigation builds voxels for world geometry.
Basically voxel size is 1 / "cell size". To reduce amount of voxels we apply scale factor, to make voxel size
"recast scale factor" / "cell size". Default value calculates by this equation:
sStepSizeUp * "recast scale factor" / "cell size" = 4 (max climb height should be equal to 4 voxels).
sStepSizeUp * "recast scale factor" / "cell size" = 5 (max climb height should be equal to 4 voxels).
Changing this value will change generated nav mesh. Some locations may become unavailable for NPC and creatures.
Pay attention to slopes and roofs when change it. Increasing this value will reduce nav mesh update latency.

View file

@ -642,8 +642,8 @@ enable = true
# Scale of NavMesh coordinates to world coordinates (value > 0.0). Recastnavigation builds voxels for world geometry.
# Basically voxel size is 1 / "cell size". To reduce amount of voxels we apply scale factor, to make voxel size
# "recast scale factor" / "cell size". Default value calculates by this equation:
# sStepSizeUp * "recast scale factor" / "cell size" = 4 (max climb height should be equal to 4 voxels)
recast scale factor = 0.023529411764705882
# sStepSizeUp * "recast scale factor" / "cell size" = 5 (max climb height should be equal to 4 voxels)
recast scale factor = 0.029411764705882353
# The z-axis cell size to use for fields. (value > 0.0)
# Defines voxel/grid/cell size. So their values have significant
@ -671,7 +671,7 @@ detail sample max error = 1.0
max simplification error = 1.3
# The width and height of each tile. (value > 0)
tile size = 64
tile size = 128
# The size of the non-navigable border around the heightfield. (value >= 0)
border size = 16