mirror of https://github.com/OpenMW/openmw.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.9 KiB
C++
77 lines
2.9 KiB
C++
#include "recastmesh.hpp"
|
|
|
|
#include "detourdebugdraw.hpp"
|
|
|
|
#include <components/detournavigator/recastmesh.hpp>
|
|
#include <components/detournavigator/recastmeshbuilder.hpp>
|
|
#include <components/detournavigator/settings.hpp>
|
|
|
|
#include <RecastDebugDraw.h>
|
|
|
|
#include <osg/Group>
|
|
#include <osg/Material>
|
|
#include <osg/PolygonOffset>
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
namespace
|
|
{
|
|
std::vector<float> calculateNormals(const std::vector<float>& vertices, const std::vector<int>& indices)
|
|
{
|
|
std::vector<float> result(indices.size());
|
|
for (std::size_t i = 0, n = indices.size(); i < n; i += 3)
|
|
{
|
|
const float* v0_ptr = &vertices[indices[i] * 3];
|
|
const float* v1_ptr = &vertices[indices[i + 1] * 3];
|
|
const float* v2_ptr = &vertices[indices[i + 2] * 3];
|
|
const osg::Vec3f v0(v0_ptr[0], v0_ptr[1], v0_ptr[2]);
|
|
const osg::Vec3f v1(v1_ptr[0], v1_ptr[1], v1_ptr[2]);
|
|
const osg::Vec3f v2(v2_ptr[0], v2_ptr[1], v2_ptr[2]);
|
|
const osg::Vec3f e0 = v1 - v0;
|
|
const osg::Vec3f e1 = v2 - v0;
|
|
osg::Vec3f normal = e0 ^ e1;
|
|
normal.normalize();
|
|
for (std::size_t j = 0; j < 3; ++j)
|
|
result[i + j] = normal[j];
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
namespace SceneUtil
|
|
{
|
|
osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
|
|
const DetourNavigator::RecastSettings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet)
|
|
{
|
|
using namespace DetourNavigator;
|
|
|
|
const osg::ref_ptr<osg::Group> group(new osg::Group);
|
|
|
|
DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, 0), 1.0f);
|
|
const DetourNavigator::Mesh& mesh = recastMesh.getMesh();
|
|
std::vector<int> indices = mesh.getIndices();
|
|
std::vector<float> vertices = mesh.getVertices();
|
|
|
|
for (const Heightfield& heightfield : recastMesh.getHeightfields())
|
|
{
|
|
const Mesh heightfieldMesh = makeMesh(heightfield);
|
|
const int indexShift = static_cast<int>(vertices.size() / 3);
|
|
std::copy(heightfieldMesh.getVertices().begin(), heightfieldMesh.getVertices().end(),
|
|
std::back_inserter(vertices));
|
|
std::transform(heightfieldMesh.getIndices().begin(), heightfieldMesh.getIndices().end(),
|
|
std::back_inserter(indices), [&](int index) { return index + indexShift; });
|
|
}
|
|
|
|
for (std::size_t i = 0; i < vertices.size(); i += 3)
|
|
std::swap(vertices[i + 1], vertices[i + 2]);
|
|
|
|
const auto normals = calculateNormals(vertices, indices);
|
|
const auto texScale = 1.0f / (settings.mCellSize * 10.0f);
|
|
duDebugDrawTriMeshSlope(&debugDraw, vertices.data(), static_cast<int>(vertices.size() / 3), indices.data(),
|
|
normals.data(), static_cast<int>(indices.size() / 3), settings.mMaxSlope, texScale);
|
|
|
|
return group;
|
|
}
|
|
}
|